请教算法,十万火急!!

a11s 2004-05-07 12:03:43
我的一个朋友需要帮助,他们考试用,大概5月9日需要这个问题的答案
我没有想出好的办法,只好请大家帮忙了

一个数学问题 任意给定4个数字 通过 + - * / () 运算 等于24
是一个证明题,列出全部的答案.

由于平时的工作很少研究算法了,做这道题的时候感觉力不从心,时间很短,不知道自己能不能作出来,谢谢大家了
...全文
92 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
recollectpainer 2004-05-09
  • 打赏
  • 举报
回复
不过我觉得那段代码需要改进
1、 全排列的问题
这个程序中用到的是4个元素,所以用 if ... goto 来做还不会引起太大的问题
但如果要做全排列的元素多一些用这个方法就不好了
搜索了一下以往的贴子,觉得有一个思路不错
就是那个对《指定数组》前N个元素作全排列的递归算法不错,昨晚回家后也写了个
大家可以搜索一下《排列》关键字就能找到

2、 northwolves(野性的呼唤) 提到的 忽略了所有(a#b)#(c#d)的情况
这个我还没考虑,呆会想想

3、 你提到的括号问题我的本意是不管三七二十七的乱加一通的,呵呵
即我把求出来的结果输出时改一下
(ps:on 即为 OperateNumber os 即为OperateSymbolString):

"(((" & on(1) & os(1) & on(2) & ")" & os(2) & on(3) & ")" & os(3) & on(4) & ")"
piminghui1979 2004-05-08
  • 打赏
  • 举报
回复
学习一下。
flyingscv 2004-05-08
  • 打赏
  • 举报
回复
发现bug

Dim OperateNumber(1 To 4, 1 To 24) As String' 24 即为 P(4,4)排列
这里有问题,改为Dim OperateNumber(1 To 4, 1 To 24) As Integer之类就可以了

--------------
Select Case Mid(OperateSymbolString(j), 1, 1)
Case "+"
tmpDouble = OperateNumber(1, i) + OperateNumber(2, i)

------------------------
如果是string类型,当第一个操作符是"+"时,这里进行的是字符串加,而不是数字加
比如:
Ns(1) = 2
Ns(2) = 4
Ns(3) = 1
Ns(4) = 1

northwolves 2004-05-08
  • 打赏
  • 举报
回复
recollectpainer(忆苦儿)写的不错,但忽略了所有(a#b)#(c#d)的情况。
ryuginka 2004-05-08
  • 打赏
  • 举报
回复
up
flyingscv 2004-05-08
  • 打赏
  • 举报
回复
recollectpainer(忆苦儿)的不错
就是缺少括号,呵呵,还有负数,有意思
puhaohmaru 2004-05-08
  • 打赏
  • 举报
回复
学习一下
broown 2004-05-08
  • 打赏
  • 举报
回复
up吧!
pigsanddogs 2004-05-07
  • 打赏
  • 举报
回复
网上的, 没仔细看。

// + - * / -- -/
// 0 1 2 3 4 5

#include<stdio.h>
#include<math.h>

int treat(float a,float b,float c,float d);
float myF(int flag,float m,float n);
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d);

int time,temp=0;
void main()
{
int i,j,k,t,again,res,flag;
float num[4];
again=1;
while(again==1)
{
printf ("\nPlease Enter 4 nums(1~13):\n");
i=0;
flag=0;
while (flag==0)
{
i++;
// printf ("Input num-%d\n",i);
for(i=0;i<4;i++)
{
scanf("%f",&num[i]);
if (num[i]<1 || num[i]>13 || num[i]!=int(num[i]))
flag++;
}
if(flag!=0)
{
printf ("Error input again\n",i);
flag=0;
}
else
flag=1;
}
for (i=0;i<4;i++)
for (j=0;j<4;j++)
if (j!=i)
for (k=0;k<4;k++)
if (k!=j && k!=i)
for (t=0;t<4;t++)
if (t!=i && t!=j && t!=k)
{
res=treat(num[i],num[j],num[k],num[t]);
}
if (res==0)
printf ("\nNo answer\n");
else ;
// printf ("time=%d\n\n",time);
printf ("\n1: Go on\n2: Quit\n");
scanf ("%d",&again);
}
}

int treat(float a,float b,float c,float d)
{
int i,j,k;
float sum1,sum2,sum3;
for (i=0;i<4;i++)
for (j=0;j<6;j++)
for (k=0;k<6;k++)
{
if ((!(i==3 && b==0)) && (!(j==3 && c==0)) && (!(k==3 && d==0)))
{
sum1=myF(i,a,b);
sum2=myF(j,sum1,c);
sum3=myF(k,sum2,d);
if (fabs(sum3-24)<0.1)
{
temp++;
myPrint(1,i,j,k,a,b,c,d);
// printf ("sum1:myF(%d,%2.0f,%2.0f) sum1=%f\n",i,a,b,sum1);
// printf ("sum2:myF(%d,%2.0f,%2.0f) sum2=%f\n",j,c,d,sum2);
// printf ("1:myF(%d,myF(%d,myF(%d,%2.0f,%2.0f),%2.0f),%2.0f) sum3=%f\n\n",k,j,i,a,b,c,d,sum3);
}
}
if (k==2)
{
sum1=myF(i,a,b);
sum2=myF(j,c,d);
sum3=sum1*sum2;
if (fabs(sum3-24)<0.1)
{
temp++;
myPrint(2,i,j,k,a,b,c,d);
// printf ("sum1:myF(%d,%2.0f,%2.0f) sum1=%f\n",i,a,b,sum1);
// printf ("sum2:myF(%d,%2.0f,%2.0f) sum2=%f\n",j,c,d,sum2);
// printf ("2:myF(%d,myF(%d,%2.0f,%2.0f),myF(%d,%2.0f,%2.0f)) sum3=%f\n\n",k,i,a,b,j,c,d,sum3);
}
}

if (k==3)
{
sum1=myF(i,a,b);
sum2=myF(j,c,d);
if (sum2!=0)
{
sum3=sum1/sum2;
if (fabs(sum3-24)<0.1)
{
temp++;
myPrint(3,i,j,k,a,b,c,d);
// printf ("sum1:myF(%d,%2.0f,%2.0f) sum1=%f\n",i,a,b,sum1);
// printf ("sum2:myF(%d,%2.0f,%2.0f) sum2=%f\n",j,c,d,sum2);
// printf ("3:myF(%d,myF(%d,%2.0f,%2.0f),myF(%d,%2.0f,%2.0f)) sum3=%f\n\n",k,i,a,b,j,c,d,sum3);
}
}
}
}
if (temp==0)
return 0;
else
return 1;
}

float myF(int flag,float m,float n)
{
// time++;
if (flag==0)
return (m+n);
if (flag==1)
return (m-n);
if (flag==2)
return (m*n);
if (flag==3)
if (n==0)
return 30000;
else
return (m/n);
if (flag==4)
return (n-m);
if (flag==5)
if (m==0)
return 30000;
else
return (n/m);
return 0;
}

void myPrint(int type,int i,int j,int k,float a,float b,float c,float d)
{
char sigle[6];
sigle[0]='+';
sigle[1]='-';
sigle[2]='*';
sigle[3]='/';
sigle[4]='-';
sigle[5]='/';
if (type==1){
if(j==4 || j==5)
{
if (k==4 || k==5)
printf("%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
else
printf("(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
}
else if (k==4 || k==5)
{
printf("%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
}
else
printf("((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
}
if (type==2 || type==3)
{
// if (k==4 || k==5)
// printf("(%2.0f %c %2.0f) %c (%2.0f %c %2.0f)=24\n",c,sigle[j],d,sigle[k],a,sigle[i],b);
// else
printf("(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
}
}

a11s 2004-05-07
  • 打赏
  • 举报
回复
我先看看,谢谢
rickytwice 2004-05-07
  • 打赏
  • 举报
回复
我作如下想法供参考:(不知可行否)

1. 首先考虑两个数的情况
很简单 F(a,b) 可返回六种情况(a+ - * /b, b- /a).
2. 再考虑三个数据情况
H(a,b,c)=F(F(a,b),c), H(a,c,b)=F(F(a,c),b), H(b,c,a)=F(F(b,c),a)
3. 最后四个数据情况
L(a,b,c,d)=F(H(a,b,c),d)....
L(d,c,b,a)=F(H(d,c,b),a)
好象有点乱,用递归?
:)我有空再自己试试.
ZhangYv 2004-05-07
  • 打赏
  • 举报
回复
http://search.csdn.net/expert/topic/6/603/2003/9/22/2285828.xml

在专题开发版若干个月前就讨论过了,搜历史旧贴,有很多的
a11s 2004-05-07
  • 打赏
  • 举报
回复
给个例子吧,我验证一下.您的意思我明白.可能是我理解能力太差,还是不能吧代码写出来
谢谢,分不是问题,我会另外开帖答谢最好的答案.这个200分帖子大家分就是了.所以有神么办法大家给演示
recollectpainer 2004-05-07
  • 打赏
  • 举报
回复
嘿嘿,200分,我还是头次就一次骗到200分呢,哈
recollectpainer 2004-05-07
  • 打赏
  • 举报
回复
楼主的意思应该是要用一个无穷例证法把所有的可能性都尝试一下
然后把满足结果为24的算法输出,不知我理解对不对?

简单分析了一下,应该分步实现,逐步把问题简化
1、四个数字应为 n1 n2 n3 n4
因为24求解是不允许数字被复用的,所以这应该是一个排列问题
将排列结果保存起来
2、运算符有 + - * / 四种,括号不考虑,他只是提高优先级的
运算符可以复用,4个数字之间应为3个运算符
所以这应该是一个求密码字典的方法,位长为3位,字符为4个
3、两层循环:第一层取第一步的结果,第二层取第二步的结果
将第二步的结果中每一项代入第一步的结果中,注意因存在优先级的问题
所以应算一步即保存一次结果,如:
第一步中某个结果为: n1 n2 n3 n4
第二步中某个结果为: + + /
则第三步中的该次代入程序应为
t1 = n1 + n2
t2 = t1 + n3
t3 = t2 / n4

这样应该解决了吧?
aiirii 2004-05-07
  • 打赏
  • 举报
回复
關注
thirdapple 2004-05-07
  • 打赏
  • 举报
回复
穷举
a11s 2004-05-07
  • 打赏
  • 举报
回复
网上有例子,但是我不知道怎么做的
http://www.2196828.com/yusoft/soft/1130.htm

谢谢大家的帮助
a11s 2004-05-07
  • 打赏
  • 举报
回复
如果有人关注请Mark一下,我好心里有数.谢谢了.实在是太急了
a11s 2004-05-07
  • 打赏
  • 举报
回复
例如: debug.print function Math24(5,5,5,4) as string
如果存在这样的算是 5*5-5+4=24 则显示出来
加载更多回复(12)

7,759

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧