输入1-10之间的4个数,每个数只能出现一次。无论使用+-*/或者(),使最后结果等于24;输出所有能实现的算法。
很复杂吧,问了N个人,发了N张贴,求高人一定帮一下。
廿四点游戏程序。
在1~10范围内共有715种出牌。当符号常量DIN==int时,有159种无法实现24点;当DIN==double时,有153种无法实现24点。实数除法比整除新增的6组解如下
(5-1/5)×5 (2+4/10)×10 (5-2/10)×5
(2+10/7)×7 (3+3/7)×7 (4-4/7)×7
/*24points.c*/
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define EPS 1e-8
#define DIN double /*或int*/
#define MAX 10 /*或13 */
char strs[12],operator[ ][3]={“+”,“-”,“×”,“÷”};
DIN ans(int iop,DIN x,DIN y)
{ switch(iop)
{ case 1 : return x+y;
case 2 : return x-y;
case 3 : return x*y;
case 4 : if(y)if(sizeof(DIN)==sizeof(int)&&(int)x%(int)y==0
||sizeof(DIN)==sizeof(double))return x/y;
default: return -1; }
}
int ok2(DIN x,DIN y)
{ int ix; for(ix=1; ix<=4; ix++)
if(fabs(ans(ix,x,y)-24)<EPS)return(ix);
return(0);
}
int ok3(DIN a,DIN b,DIN c)
{ int i,j,k; DIN x[3];
x[0]=a; x[1]=b; x[2]=c;
for(i=0; i<3; i++)
for(j=0; j<3; j++)if(j!=i)
for(k=0; k<3; k++)if(k!=i && k!=j)
{ int ix,imid; DIN y;
for(ix=1; ix<=4; ix++)
{ y=ans(ix,x[i],x[j]); if(y<=0)continue;
if((imid=ok2(y,x[k]))!=0)
{ if(i==0)printf(“(%s%s%d)%s%d\n”,strs,operator[ix-1],
(int)x[j],operator[imid-1],(int)x[k]);
else if(j==0)printf(“(%d%s%s)%s%d\n”,(int)x[i],operator[ix-1],
strs,operator[imid-1],(int)x[k]);
else if(k==0)printf(“(%d%s%d)%s%s\n”,(int)x[i],operator[ix-1],
(int)x[j],operator[imid-1],strs);
return(1);
}
}
} return(0);
}
int point24(int p[4])
{ int a,b,c,d,i,ix; DIN y;
for(a=0; a<4; a++)
for(b=0; b<4; b++)if(b!=a)
for(c=0; c<4; c++)if(c!=a && c!=b)
for(d=0; d<4; d++)if(d!=a && d!=b && d!=c)
for(ix=1; ix<=4; ix++)
{ y=ans(ix,p[a],p[b]); if(y<=0)continue;
strs[0]=‘(’; itoa(p[a],&strs[1],10);
strcat(strs,operator[ix-1]); i=strlen(strs);
itoa(p[b], &strs[i],10); i=strlen(strs);
strs[i]=‘)’; strs[i+1]=‘\0’;
if(ok3(y,p[c],p[d]))return(1);
} return(0);
} /* itoa(p[a],&strs[1],10)将p[a]的值按10进制转换成字符串存入&strs[1]*/
main( )
{ int p[4],total,cannot; printf(“4 cards: ”);
scanf(“%d%*c%d%*c%d%*c%d”,p,p+1,p+2,p+3);
point24(p);
/************以下做全面检测********************************************
total=0; cannot=0;
for(p[0]= 1 ; p[0]<=MAX; p[0]++)
for(p[1]=p[0]; p[1]<=MAX; p[1]++)
for(p[2]=p[1]; p[2]<=MAX; p[2]++)
for(p[3]=p[2]; p[3]<=MAX; p[3]++)
{ total++; if(!point24(p)){ cannot++;
printf(“%d,%d,%d,%d\n”,p[0],p[1],p[2],p[3]); }
} printf(“MAX=%d,TOTAL=%d,CANNOT=%d\n”,MAX,total,cannot);
***********************************************************************/
}
运行情况:若键入 1,5,5,5 ↙ 则输出 (5-(1÷5))×5
若键入 4,4,7,7 ↙ 则输出 (4-(4÷7))×7
若键入 4,9,6,12 ↙ 则输出 ((4+12)×9)÷6
若键入 4,9,6,11 ↙ 无输出 (表示无法形成24点)
对以上程序ex6-49.c的几点说明。①主函数提示用户输入4张牌的点数并将它们存入数组p[],然后调用point24函数。②point24函数是一5重循环,外围4重产生4张牌的全排列p[a]p[b]p[c]p[d];内层ix循环(通过ans函数)先后产生p[a],p[b]的和差积商,并将它存入y变量(这样一来就退化为“3张牌”问题)…(略去细节)…然后调用ok3函数。若ok3返回1则立即从5重循环中退出并返回1;否则继续循环。5重循环完毕若仍未果则返回0。③ok3函数的思路与point24()如出一辙。3层外循环产生“3张牌”x[i]x[j]x[k]的全排列,内层ix(此ix非彼ix)循环将x[i],x[j]的和差积商之一存入(本地的)y变量,从而退化为“2张牌”的问题。接着调用ok2函数,若ok2返回非零值则显示该24点问题的一种解法,然后从4重循环中退出并返回1;否则继续循环。若4重循环完未果则返回0。④ok2函数确定“2张牌”能否形成24点,若不能则返回0,否则返回1~4(加减乘除)中的某个数。⑤ans函数将加减乘除四则运算序数化为1~4,以便纳入循环操作的轨道。
--------------------Configuration: tc - Win32 Debug--------------------
Compiling...
tc.cpp
E:\test\c\test\tc.cpp(9) : error C2440: 'initializing' : cannot convert from 'char [5]' to 'char'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
E:\test\c\test\tc.cpp(11) : error C2543: expected ']' for operator '[]'
E:\test\c\test\tc.cpp(11) : error C2146: syntax error : missing ')' before identifier 'ith'
E:\test\c\test\tc.cpp(11) : error C2143: syntax error : missing ';' before ']'
E:\test\c\test\tc.cpp(11) : warning C4552: '-' : operator has no effect; expected operator with side-effect
E:\test\c\test\tc.cpp(11) : warning C4060: switch statement contains no 'case' or 'default' labels
E:\test\c\test\tc.cpp(11) : error C2059: syntax error : ')'
E:\test\c\test\tc.cpp(12) : error C2143: syntax error : missing ';' before '{'
E:\test\c\test\tc.cpp(12) : error C2046: illegal case
E:\test\c\test\tc.cpp(13) : error C2046: illegal case
E:\test\c\test\tc.cpp(14) : error C2046: illegal case
E:\test\c\test\tc.cpp(15) : error C2046: illegal case
E:\test\c\test\tc.cpp(17) : error C2047: illegal default
E:\test\c\test\tc.cpp(74) : warning C4508: 'main' : function should return a value; 'void' return type assumed
Error executing cl.exe.
tc.obj - 11 error(s), 3 warning(s)