发信人: yangcs()
整理人: yangcs(2000-03-08 18:37:40), 站内信件
|
方法一: # include <stdio.h> # include <math.h> # define EPS 0.001 // 出现0或负数就不必再往下算了 float f1(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retur n x+y; } float f2(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retu rn x-y; } float f3(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retu rn x*y; } float f4(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retu rn x/y; }
void main() { int a,b,c,d,i,j,k,m,n,f24; char s[10000][40]; // 其实s[1000][40]就够了,用来存算24的方法 char fh[4]; // fh[0]='+'; fh[1]='-'; fh[2]='*'; fh[3]='/'; float x[4]; // 用实数记录三张扑克,其实用4个实型变量即可 float (*(p[4]))(float,float); //四个函数指针,用来做四种运算 int flag[10000]; /* 1到10四个数顺序共10000种组合 */
fh[0]='+'; fh[1]='-'; fh[2]='*'; fh[3]='/'; for(a=0;a<10000;a++) flag[a]=0; /* 初值,不能算24的 */ p[0]=f1;p[1]=f2;p[2]=f3;p[3]=f4;
// 为了编程方便起见,我让四张扑克a,b,c,d都从1循环到10,循环10000次 for(m=n=a=0;a<10;a++) for(b=0;b<10;b++) for(c=0;c<10;c++) for(d=0;d<10;d++,n++) { // printf("%d %d %d %d %d\n",a,b,c,d,n); if(flag[n]) continue; x[0]=(float) (a+1);x[1]=(float) (b+1); x[2]=(float) (c+1);x[3]=(float) (d+1); f24=1; // i,j,k循环,填写三个符号,共4*4*4次 for(i=0;(i<4)&&f24;i++) for(j=0;(j<4)&&f24;j++) for(k=0;(k<4)&&f24;k++) { // 括号共有五种组合 if(fabs(p[k](p[j](p[i](x[0],x[1]),x[2]),x[3])-24)<EPS) { sprintf(s[m],"A ((%d%c%d)%c%d)%c%d",a+1,fh[i],b+1,fh[j],c+1,fh[k], d+1); f24=0;break; } if(fabs(p[j](p[i](x[0],x[1]),p[k](x[2],x[3]))-24)<EPS) { sprintf(s[m],"B (%d%c%d)%c(%d%c%d)",a+1,fh[i],b+1,fh[j],c+1,fh[k], d+1); f24=0;break; } if(fabs(p[k](p[i](x[0],p[j](x[1],x[2])),x[3])-24)<EPS) { sprintf(s[m],"C (%d%c(%d%c%d))%c%d",a+1,fh[i],b+1,fh[j],c+1,fh[k], d+1); f24=0;break; } if(fabs(p[i](x[0],p[k](p[j](x[1],x[2]),x[3]))-24)<EPS) { sprintf(s[m],"D %d%c((%d%c%d)%c%d)",a+1,fh[i],b+1,fh[j],c+1,fh[k], d+1); f24=0;break; } if(fabs(p[i](x[0],p[j](x[1],p[k](x[2],x[3])))-24)<EPS) { sprintf(s[m],"E %d%c(%d%c(%d%c%d))",a+1,fh[i],b+1,fh[j],c+1,fh[k], d+1); f24=0;break; } } // a,b,c,d有一种组合能算出24,则它的任何一种排列都能用同样方法算24。
// 这24种排列方法我就不重新写程序了,我直接赋值 // 全排列程序在精华区里有,阿豪和我的程序最快 if(!f24) { //printf("%4d:%s\n",m,s[m]); m++; // 下列赋值语句是我把全排列程序稍加改动生成的 // 阿蓉说的没错,全排列程序确实在很多场合下用得到 flag[a*1000+b*100+c*10+d]=m; flag[b*1000+a*100+c*10+d]=m; flag[a*1000+c*100+b*10+d]=m; flag[c*1000+a*100+b*10+d]=m; flag[b*1000+c*100+a*10+d]=m; flag[c*1000+b*100+a*10+d]=m; flag[a*1000+b*100+d*10+c]=m; flag[b*1000+a*100+d*10+c]=m; flag[a*1000+d*100+b*10+c]=m; flag[d*1000+a*100+b*10+c]=m; flag[b*1000+d*100+a*10+c]=m; flag[d*1000+b*100+a*10+c]=m; flag[a*1000+c*100+d*10+b]=m; flag[c*1000+a*100+d*10+b]=m; flag[a*1000+d*100+c*10+b]=m; flag[d*1000+a*100+c*10+b]=m; flag[c*1000+d*100+a*10+b]=m; flag[d*1000+c*100+a*10+b]=m; flag[b*1000+c*100+d*10+a]=m; flag[c*1000+b*100+d*10+a]=m; flag[b*1000+d*100+c*10+a]=m; flag[d*1000+b*100+c*10+a]=m; flag[c*1000+d*100+b*10+a]=m; flag[d*1000+c*100+b*10+a]=m; } } // 以上循环如果不考虑中途退出(如果想把所有算24的方法列出), // 共要循环10*10*10*10*4*4*4*5 = 3,200,000次, // 实际运算次数远远小于这个数。 // 当然,这种方法重复计算很多,但实际运行时间为1秒钟左右, // 我就不必计较算法的快慢,只计较程序的可读性了。
// 四张扑克从小到大排列,共有下列种情况能算出24 for(a=0;a<10;a++) for(b=a;b<10;b++) for(c=b;c<10;c++) for(d=c;d<10;d++) { n=a*1000+b*100+c*10+d; if(flag[n]) printf("%2d %2d %2d %2d: %s\n",a+1,b+1,c+1,d+1,s[flag[n]-1]); }
// 另一种输出方式,可以算出任意抽取四张扑克,能算出24的概率 for(m=a=0;a<10;a++) for(b=0;b<10;b++) for(c=0;c<10;c++) for(d=0;d<10;d++) { n=a*1000+b*100+c*10+d; if(flag[n]) printf("%4d:%2d %2d %2d %2d: %s\n",++m,a+1,b+1,c+1,d+1,s[flag[n ]-1]); } }
方法二:
# include <stdio.h> # include <math.h> # define EPS 0.001 // 出现0或负数就不必再往下算了 float f1(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retur n x+y; } float f2(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retu rn x-y; } float f3(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retu rn x*y; } float f4(float x,float y) { if ((x<EPS)||(y<EPS)) return 0; else retu rn x/y; } int func(float,float,float,float); int a,b,c,d,i,j,k,m,n,f24; char fh[4]; // fh[0]='+'; fh[1]='-'; fh[2]='*'; fh[3]='/'; float x0,x1,x2,x3; // 用实数记录三张扑克 float (*(p[4]))(float,float); //四个函数指针,用来做四种运算 void main() { fh[0]='+'; fh[1]='-'; fh[2]='*'; fh[3]='/'; p[0]=f1;p[1]=f2;p[2]=f3;p[3]=f4;
for(m=n=a=0;a<10;a++) for(b=a;b<10;b++) for(c=b;c<10;c++) for(d=c;d<10;d++,n++) { x0=(float) (a+1);x1=(float) (b+1); x2=(float) (c+1);x3=(float) (d+1); f24=1; for(i=0;(i<4)&&f24;i++) for(j=0;(j<4)&&f24;j++) for(k=0;(k<4)&&f24;k++) { if(!(f24=func(x0,x1,x2,x3))) break; if(!(f24=func(x1,x0,x2,x3))) break; if(!(f24=func(x0,x2,x1,x3))) break; if(!(f24=func(x2,x0,x1,x3))) break; if(!(f24=func(x1,x2,x0,x3))) break; if(!(f24=func(x2,x1,x0,x3))) break; if(!(f24=func(x0,x1,x3,x2))) break; if(!(f24=func(x1,x0,x3,x2))) break; if(!(f24=func(x0,x3,x1,x2))) break; if(!(f24=func(x3,x0,x1,x2))) break; if(!(f24=func(x1,x3,x0,x2))) break; if(!(f24=func(x3,x1,x0,x2))) break; if(!(f24=func(x0,x2,x3,x1))) break; if(!(f24=func(x2,x0,x3,x1))) break; if(!(f24=func(x0,x3,x2,x1))) break; if(!(f24=func(x3,x0,x2,x1))) break; if(!(f24=func(x2,x3,x0,x1))) break; if(!(f24=func(x3,x2,x0,x1))) break; if(!(f24=func(x1,x2,x3,x0))) break; if(!(f24=func(x2,x1,x3,x0))) break; if(!(f24=func(x1,x3,x2,x0))) break; if(!(f24=func(x3,x1,x2,x0))) break; if(!(f24=func(x2,x3,x1,x0))) break; if(!(f24=func(x3,x2,x1,x0))) break; } if(!f24) m++; } printf("m=%d n=%d\n",m,n); }
int func(float x0,float x1,float x2,float x3) { if(fabs(p[k](p[j](p[i](x0,x1),x2),x3)-24)<EPS) { printf("A ((%d%c%d)%c%d)%c%d\n",a+1,fh[i],b+1,fh[j],c+1,fh[k],d+1) ; return 0; } if(fabs(p[j](p[i](x0,x1),p[k](x2,x3))-24)<EPS) { printf("B (%d%c%d)%c(%d%c%d)\n",a+1,fh[i],b+1,fh[j],c+1,fh[k],d+1) ; return 0; } if(fabs(p[k](p[i](x0,p[j](x1,x2)),x3)-24)<EPS) { printf("C (%d%c(%d%c%d))%c%d\n",a+1,fh[i],b+1,fh[j],c+1,fh[k],d+1) ; return 0; } if(fabs(p[i](x0,p[k](p[j](x1,x2),x3))-24)<EPS) { printf("D %d%c((%d%c%d)%c%d)\n",a+1,fh[i],b+1,fh[j],c+1,fh[k],d+1) ; return 0; } if(fabs(p[i](x0,p[j](x1,p[k](x2,x3)))-24)<EPS) { printf("E %d%c(%d%c(%d%c%d))\n",a+1,fh[i],b+1,fh[j],c+1,fh[k],d+1) ; return 0; } return 1; }
方法三:主程序同方法二,func()的函数内容:
int func(float x0,float x1,float x2,float x3) { // 列出所有情况,…… }
这段程序将会很长,但可以先编写另一段程序生成这段程序,这种方法在实 际 编程中经常使用。
-- 欢迎来到DOS版。那里有一只老羊和一条小狼和sle。 [email protected]
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 210.72.45.132]
|
|