一个C程序设计题,高手请进!
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个C程序设计题,高手请进!相关的知识,希望对你有一定的参考价值。
1~10十个数字,从其中任意取出四个数字,把他们用加减乘除计算,使得这些数字计算出来的点数正好为24(即常玩的二十四点游戏)
如 1 2 6 8则(6-2-1)*8=24,又如10 10 10 10 就无法可想了.
编程要求:
一、统计出求不出24的所有组合数目.
二、将没一种组合的计算结果写入文件result.txt,每两组一行.
补充:注意冗余的情况
如:1 2 1 2 和1 2 2 1 就是同一组数据.
最好用函数递归计算:
形如:f(a,b,c,d)→g(e,c,d)→h(f,d)→24;
修改一下,不一定要用递归了.
用四个数组放四个数字,然后象其中插入运算符,这样比较好穷举.
但是冗余的情况一定要排除,还有如:1 5 5 5 (5-1/5)*5=24 这样的情况,就还要考虑浮点数还有其精度问题.
#include <memory.h>
//中间数据,用于生成算式
int g_Order[3][4];//调用顺序
int g_Operator[3];//三次计算的运行符,1-加 2-减 3-倒减 4-乘 5-除 6-倒除
bool Is24(double fNum)
double fDif=fNum-24;
if(fDif<0)
fDif=-fDif;
if(fDif<0.00001)
return true;
else
return false;
bool Cal2(double fNum1,double fNum2)
//看2个数是否满足条件
g_Operator[2]=1;
if(Is24(fNum1+fNum2))
return true;
g_Operator[2]=2;
if(Is24(fNum1-fNum2))
return true;
g_Operator[2]=4;
if(Is24(fNum1*fNum2))
return true;
g_Operator[2]=5;
if(fNum2!=0&&Is24(fNum1/fNum2))
return true;
return false;
bool Order2(double fNum1,double fNum2)
double fTemp[2];
int i,j;
fTemp[0]=fNum1;
fTemp[1]=fNum2;
for(i=0;i<2;i++)
//数字1从3个中选择一个
for(j=0;j<2;j++)
//数字2从余下的2个中选一个
if(i!=j)
g_Order[2][0]=i;g_Order[2][1]=j;
if(Cal2(fTemp[i],fTemp[j]))
return true;
return false;
bool Cal3(double fNum1,double fNum2,double fNum3)
//看3个数是否满足条件
g_Operator[1]=1;
if(Order2(fNum1+fNum2,fNum3))
return true;
g_Operator[1]=2;
if(Order2(fNum1-fNum2,fNum3))
return true;
g_Operator[1]=4;
if(Order2(fNum1*fNum2,fNum3))
return true;
g_Operator[1]=5;
if(fNum2!=0&&Order2(fNum1/fNum2,fNum3))
return true;
return false;
bool Order3(double fNum1,double fNum2,double fNum3)
double fTemp[3];
int i,j,k;
fTemp[0]=fNum1;
fTemp[1]=fNum2;
fTemp[2]=fNum3;
for(i=0;i<3;i++)
//数字1从3个中选择一个
for(j=0;j<3;j++)
//数字2从余下的2个中选一个
if(i!=j)
for(k=0;k<3;k++)
if(k!=i&&k!=j)
g_Order[1][0]=i;g_Order[1][1]=j;g_Order[1][2]=k;
if(Cal3(fTemp[i],fTemp[j],fTemp[k]))
return true;
return false;
bool Cal4(double fNum1,double fNum2,double fNum3,double fNum4)
//看4个数是否满足条件
g_Operator[0]=1;
if(Order3(fNum1+fNum2,fNum3,fNum4))
return true;
g_Operator[0]=2;
if(Order3(fNum1-fNum2,fNum3,fNum4))
return true;
g_Operator[0]=4;
if(Order3(fNum1*fNum2,fNum3,fNum4))
return true;
g_Operator[0]=5;
if(fNum2!=0&&Order3(fNum1/fNum2,fNum3,fNum4))
return true;
return false;
bool Order4(double fNum1,double fNum2,double fNum3,double fNum4)
//i,j,k,l四个数字进行组合调用(因为在Cal4中没有考虑到计算的先后,所以在这里面要进行。)
double fTemp[4];
int i,j,k,l;
fTemp[0]=fNum1;
fTemp[1]=fNum2;
fTemp[2]=fNum3;
fTemp[3]=fNum4;
for(i=0;i<4;i++)
//数字1从4个中选择一个
for(j=0;j<4;j++)
//数字2从余下的三个中选一个
if(i!=j)
for(k=0;k<4;k++)
//数字3从余下的二个中选一个
if(k!=i&&k!=j)
for(l=0;l<4;l++)
if(l!=i&&l!=j&&l!=k)
g_Order[0][0]=i;g_Order[0][1]=j;g_Order[0][2]=k;g_Order[0][3]=l;
if(Cal4(fTemp[i],fTemp[j],fTemp[k],fTemp[l]))
return true;
return false;
char GetOper(int nOperator)
switch(nOperator)
case 1:
return '+';
case 2:
return '-';
case 4:
return '*';
case 5:
return '/';
return '\0';
void GetCalString(char *cBuf,int i,int j,int k,int l)
//生成算式
//int g_Order[3][4];//调用顺序
//int g_Operator[3];//三次计算的运行符,1-加 2-减 3-倒减 4-乘 5-除 6-倒除
int nNum[4];
int nTemp[4];
nTemp[0]=i;nTemp[1]=j;nTemp[2]=k;nTemp[3]=l;
nNum[0]=nTemp[g_Order[0][0]];
nNum[1]=nTemp[g_Order[0][1]];
nNum[2]=nTemp[g_Order[0][2]];
nNum[3]=nTemp[g_Order[0][3]];
char cTemp[3][100];
memset(cTemp[0],0,100);
sprintf(cTemp[0],"(%d%c%d)",nNum[0],GetOper(g_Operator[0]),nNum[1]);
nNum[0]=nNum[g_Order[1][0]+1];
nNum[1]=nNum[g_Order[1][1]+1];
nNum[2]=nNum[g_Order[1][2]+1];
memset(cTemp[1],0,100);
if(g_Order[1][0]==0)
sprintf(cTemp[1],"(%s%c%d)",cTemp[0],GetOper(g_Operator[1]),nNum[1]);
else if(g_Order[1][1]==0)
sprintf(cTemp[1],"(%d%c%s)",nNum[0],GetOper(g_Operator[1]),cTemp[0]);
else//g_Order[1][2]==0
sprintf(cTemp[1],"(%d%c%d)",nNum[0],GetOper(g_Operator[1]),nNum[1]);
memset(cTemp[2],0,100);
nNum[0]=nNum[g_Order[2][0]+1];
nNum[1]=nNum[g_Order[2][1]+1];
if(g_Order[1][2]==0)
//型如:(a+b)-(c+d)
if(g_Order[2][0]==0)
//没有倒序
sprintf(cTemp[2],"%s%c%s",cTemp[1],GetOper(g_Operator[2]),cTemp[0]);
else
sprintf(cTemp[2],"%s%c%s",cTemp[0],GetOper(g_Operator[2]),cTemp[1]);
else
//其它
if(g_Order[2][0]==0)
//没有倒序
sprintf(cTemp[2],"%s%c%d",cTemp[1],GetOper(g_Operator[2]),nNum[1]);
else
sprintf(cTemp[2],"%d%c%s",nNum[0],GetOper(g_Operator[2]),cTemp[1]);
sprintf(cBuf,"%s=24",cTemp[2]);
void main()
int i,j,k,l;
int nCount=0,nLossCount=0;
FILE *pFile=::fopen("result.txt","w+");
for(i=1;i<=10;i++)
for(j=i;j<=10;j++)
for(k=j;k<=10;k++)
for(l=k;l<=10;l++)
if(Order4(i,j,k,l))
//组织运算式
char cTemp[100];//生成运算串
::memset(cTemp,0,100);
GetCalString(cTemp,i,j,k,l);
printf("%2d,%2d,%2d,%2d %s ",i,j,k,l,cTemp);
::fprintf(pFile,"%2d,%2d,%2d,%2d %s ",i,j,k,l,cTemp);
nCount++;
if(nCount%2==0)
printf("\r\n");
fprintf(pFile,"\r\n");
else
nLossCount++;
printf("\r\n%d\r\n%d\r\n",nCount,nLossCount);
fprintf(pFile,"\r\n%d\r\n%d\r\n",nCount,nLossCount);
fclose(pFile);
参考技术A 我有java实现的24点的程序..可以去我QQ的blog上参考..c的语法和java的差不多吧..只是没有用到你说的那个递归算法..我是全都拿出来的了...
因为我考虑到的是扑克牌没有一个是一样的...就算10 和10也是有黑红梅方的区别吧... 参考技术B 如果不是实际应用的问题还真无聊,
如果是实际应用的问题,劝你绕道,大量浮点可不好玩 参考技术C 去看看http://www.dffy.com/tool/24.htm
看源文件,虽然不是用c写的,但思路很清楚
参考资料:http://www.dffy.com/tool/24.htm
参考技术D 高手们,是C程序啊.我不要那些很就以前就贴在网上的java basic程序.能自己劳动一下下帮帮忙吗?
而且那些都不具备我说的那些功能. 第5个回答 2007-07-05 留个脚印
以上是关于一个C程序设计题,高手请进!的主要内容,如果未能解决你的问题,请参考以下文章