主题:做了个算24点牌的C程序,另求算“猜数字”思想
upday
[专家分:0] 发布于 2003-10-30 18:22:00
先说“猜数字”,是不是最少7步?
//以下为24点程序//
// + - * / -- -/
// 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);
}
}
回复列表 (共57个回复)
21 楼
ychzh2000 [专家分:1750] 发布于 2004-05-30 11:22:00
如果要猜0123(即允许0开头),那么必须让n1的值从0开始,不过0123就不用猜了,因为他第一次就询问0123,呵呵。(如果不允许0开头,则第一次询问的是1023)。
例子1:答案是7390(不允许0开头),计算机询问及需要反馈的信息如下:
计算机猜的数 反馈的A B
1023 2 0
2145 0 0
3607 3 0
6380 2 2
7390 4 4
例2:答案9876(允许0开头)
1023 0 0
4567 2 0
5489 2 0
6798 4 0
8976 4 2
9876 4 4
22 楼
yczni [专家分:340] 发布于 2004-05-30 18:06:00
to 21 楼
首先要说的是猜数字是包括0开头的,也就是说包括0123
第二在猜时虽然你没有搞清楚AB代表什么意思,但你的做法和正常的并没有本质的区别,我也理解了你的AB的意思.
如果你看了我的程序的思想你会知道,我的思想和你的思想实际上是一样的.
我看了你的程序感觉到很多东西用c实现起来要比pascal容易,但是我是一个c初学者,pascal还比较熟悉,所以用pascal来编的.(我的程序还有很多可改进的地方可以用链表来做,我还不会又不想学pascal了,改c了,自我感觉c很难)
我再强调一下,猜数字是包括0开头的,也就是说包括0123.
你可以猜猜5293,9204,9214,9241,9431这5个数,按照你的做法这5个数应该是要9次才能猜出,另外有129个数需要8次才能猜出,5和129对于5040当然是很小了所以不容易发现.
但是即然你的方法已经定了,再加一重循环,检查一下每个数都要几次能猜出来,哪些数是需要8次能猜出,哪些数是需要9次能猜出,我想这应该并不困难吧.
23 楼
烟灰 [专家分:0] 发布于 2004-05-30 19:05:00
呵呵好热闹哦,``````虽然我看不懂`大家热爱C哦````````````我也想象达到你们这样的程度,来讨论这些!!!大哥多多教教小弟,我会努力学的
24 楼
yczni [专家分:340] 发布于 2004-05-30 19:16:00
其实最难猜出的是前两次有一次是0a1b,一次是0a2b;
按21楼的说法最难猜的就是前两次一次是1a0b,一次是2a0b;
25 楼
yczni [专家分:340] 发布于 2004-05-30 19:20:00
很久以前我看楼主就是只发了11个贴子,看样子楼主应该有大半年没有来了。
26 楼
ychzh2000 [专家分:1750] 发布于 2004-05-31 10:49:00
感谢yczni的指教,我再发一个程序,呵呵,这可是箱底货,它才是我最初写的程序,以前发的两个是根据这个简化的。主要的思想方法是一样的,不过这个要复杂的多,它会先询问1234和5678。这个程序刚好可以解决您提出的那5个数(3个需要6次,2个需要5次)。望yczni兄继续不吝赐教。
另外,希望朋友们告知,为什么开始那个程序在TC2下不能正确执行。
#include <stdio.h>
char scr[10][5],scr2[4][11],std[8][6],std_n,A,B,m,n,h,i,j,k,relation,next,count;
void save()
{ std[std_n][0]=A;
std[std_n][1]=scr2[0][h];
std[std_n][2]=scr2[1][i];
std[std_n][3]=scr2[2][j];
std[std_n][4]=scr2[3][k];
std[std_n][5]=B;
}
void printerr()
{printf("Error!You input wrong number!");
exit(0);
}
void ask(char n1,char n2,char n3,char n4)
{
printf("%d%d%d%d\n",n1,n2,n3,n4);
printf("A=");
scanf("%d",&A);
printf("B=");
scanf("%d",&B);
if ((B>A)||(A>4)||(A<0)||(B<0)||(B>4))
printerr();
}
void certain(char num,char pos)
{char x,y=0;
if(pos!=0)
{if ((scr[num][pos]<0)||(scr[num][0]<0)) printerr();
else
{scr[num][pos]=127;
scr[num][0] =127;
for(x=1;x<=4;x++)
if(pos!=x) clean(num,x);
for(x=0;x<=9;x++)
if(num!=x) clean(x,pos);
}
}
else /*pos==0*/
{if(scr[num][0]<0) printerr();
else
{scr[num][0]=127;
for(x=1;x<=4;x++)
if(scr[num][x]==0) y++;
if (y==1)
{for(x=1;x<=4;x++)
if(scr[num][x]==0) {certain(num,x);break;}
}
}
}
}
int clean(char num,char pos)
{char x,y=0;
if (pos!=0)
{
if (scr[num][pos]>0) printerr();
else
{scr[num][pos]=-128;
for(x=0;x<=9;x++)
if (scr[x][pos]==0) y++;
if(y==1)
{for(x=0;x<=9;x++)
{if(scr[x][pos]==0)
{certain(x,pos);
break;
}
}
}
}
}
else
{if(scr[num][0]>0) printerr();
else
{scr[num][0]=-128;
clean(num,1);
clean(num,2);
clean(num,3);
clean(num,4);
}
}
}
void createscr2()
{int x,y,z;
for(y=1;y<=4;y++)
{z=0;
for(x=0;x<=9;x++)
if (scr[x][y]>=0) scr2[y-1][++z]=x;
scr2[y-1][0]=z;
}
}
char test1()
{
if ((scr2[0][h]==scr2[1][i])||
(scr2[0][h]==scr2[2][j])||
(scr2[0][h]==scr2[3][k])||
(scr2[1][i]==scr2[2][j])||
(scr2[1][i]==scr2[3][k])||
(scr2[2][j]==scr2[3][k]))
return 0;
else return 1;
}
char test2()
{char x,y,a=0,b=0;
for (x=0;x<std_n;x++) /*check B*/
{b=0;
if (scr2[0][h]==std[x][1]) b++;
if (scr2[1][i]==std[x][2]) b++;
if (scr2[2][j]==std[x][3]) b++;
if (scr2[3][k]==std[x][4]) b++;
if(b!=std[x][5]) return 0;
}
for (x=0;x<std_n;x++) /*check A*/
{a=0;
for(y=1;y<=4;y++)
{if(scr2[0][h]==std[x][y]) a++;
if(scr2[1][i]==std[x][y]) a++;
if(scr2[2][j]==std[x][y]) a++;
if(scr2[3][k]==std[x][y]) a++;
if(a>std[x][0]) return 0;
}
if (a!=std[x][0]) return 0;
}
return 1;
}
char test90()
{char x=0;
if ((scr2[0][h]==0)||(scr2[0][h]==9)) x++;
if ((scr2[1][i]==0)||(scr2[1][i]==9)) x++;
if ((scr2[2][j]==0)||(scr2[2][j]==9)) x++;
if ((scr2[3][k]==0)||(scr2[3][k]==9)) x++;
if(x!=relation) return 0;
else return 1;
}
int main()
{
clrscr();
for(m=0;m<=9;m++)
for(n=0;n<=4;n++)
scr[m][n]=0;
count=1;
printf("1: ");
ask(1,2,3,4);
std[0][0]=A;
std[0][1]=1;
std[0][2]=2;
std[0][3]=3;
std[0][4]=4;
std[0][5]=B;
std_n=1;
if (B==4)
{printf("Haha!");
exit(0);
}
if (A==0)
{clean(1,0);
clean(2,0);
clean(3,0);
clean(4,0);
}
if (B==0)
{clean(1,1);
clean(2,2);
clean(3,3);
clean(4,4);
}
if (A==4)
{clean(5,0);
clean(6,0);
clean(7,0);
clean(8,0);
clean(9,0);
clean(0,0);
certain(1,0);
certain(2,0);
certain(3,0);
certain(4,0);
}
if (scr[5][0]>=0) /*5678 can*/
{printf("2: ");
count=2;
ask(5,6,7,8);
std[1][1]=5;
std[1][2]=6;
std[1][3]=7;
std[1][4]=8;
std[1][0]=A;
std[1][5]=B;
std_n=2;
if (B==4)
{printf("Haha!");
exit(0);
}
if (A==0)
{clean(5,0);
clean(6,0);
clean(7,0);
clean(8,0);
}
if (B==0)
{clean(5,1);
clean(6,2);
clean(7,3);
clean(8,4);
}
if (A==4)
{clean(1,0);
clean(2,0);
clean(3,0);
clean(4,0);
clean(9,0);
clean(0,0);
certain(5,0);
certain(6,0);
certain(7,0);
certain(8,0);
}
m=3;
}
else m=2;
switch (std[0][0]+std[1][0])
{
case 2:scr[0][0]=127;
scr[9][0]=127;
relation=2;
break;
case 3:relation=1;
break;
case 4:scr[0][0]=-128;
scr[9][0]=-128;
relation=0;
break;
default: printerr();
break;
}
for(;m<9;m++)
{createscr2();
next=0;
for(h=1;h<=scr2[0][0];h++)
{for(i=1;i<=scr2[1][0];i++)
{for(j=1;j<=scr2[2][0];j++)
{for(k=1;k<=scr2[3][0];k++)
{if(!test1()) continue;
if(!test2()) continue;
if(!test90())continue;
next=1;
printf("%d: ",++count);
ask(scr2[0][h],scr2[1][i],scr2[2][j],scr2[3][k]);
save();
std_n++;
if (B==4)
{printf("Haha!");
exit(0);
}
if (A==0)
{clean(scr2[0][h],0);
clean(scr2[1][i],0);
clean(scr2[2][j],0);
clean(scr2[3][k],0);
}
if (B==0)
{clean(scr2[0][h],1);
clean(scr2[1][i],2);
clean(scr2[2][j],3);
clean(scr2[3][k],4);
}
if (A==4)
{for(n=0;n<=9;n++)
{if((n==scr2[0][h])||(n==scr2[1][i])||
(n==scr2[2][j])||(n==scr2[3][k]))
certain(n,0);
else clean(n,0);
}
}
break;/*for(k)*/
}
if (next==1) break;/*for(j)*/
}
if(next==1)break;/*for(i)*/
}
if(next==1)break;/*for(h)*/
}
if(next==0) printerr();
}/*for(m)*/
}
27 楼
yczni [专家分:340] 发布于 2004-05-31 11:18:00
您猜猜8021和9715,如果思想不变每次都取最小数作为试猜的话还应该有79个数需要8次才能猜中
我的思想和您的相同.
我程序中的特殊的数,是用程序算出的较好的数,但不是最好的数,最好的要继续把类分得更细.
我对c还不太熟,乱说
不知道您是不是用了c99的标准
tc20可能不支持c99,只支持c89
28 楼
yczni [专家分:340] 发布于 2004-05-31 13:05:00
to 13楼
因为这个贴子是去年十月发起的早就沉到箱底去了,这个贴子我看到过但是没回,即使回了也没人能看到啊
后来我发现一个贴子只要有人回它就会跑到前面的页,没人回就沉箱底.
29 楼
jackin0627 [专家分:1270] 发布于 2004-05-31 13:26:00
/*用TC2.0运行*/
#include<conio.h>
#include<math.h>
#include<conio.h>
#include<string.h>
char sig[4]={'+','-','*','/'};
void fun(float n[],char ch[][50],int m)
{
int x[2],y,i,j;
float num[4];
char cc[4][50];
if(m==1)
{
if(fabs(n[0]-24.0)<0.0001)
{
printf("\n%s=24",ch[0]);
getch();
exit(0);
}
}
else
{
for(x[0]=0;x[0]<m;x[0]++)
{
for(x[1]=0;x[1]<m;x[1]++)
{
if(x[1]==x[0])continue;
for(y=0;y<4;y++)
{
switch(y)
{
case 0: num[0]=n[x[0]]+n[x[1]];break;
case 1: num[0]=n[x[0]]-n[x[1]];break;
case 2: num[0]=n[x[0]]*n[x[1]];break;
case 3: if(n[x[1]]==0)break;
num[0]=n[x[0]]/n[x[1]];break;
default:break;
}
if(y!=3||n[x[1]]!=0)
sprintf(cc[0],"(%s%c%s)",ch[x[0]],sig[y],ch[x[1]]);
for(i=0,j=1;i<m;i++)
if(i!=x[0]&&i!=x[1])
{
num[j]=n[i];
strcpy(cc[j],ch[i]);
j++;
}
fun(num,cc,m-1);
}
}
}
}
}
/***********************/
main()
{
float num[4];
int i;
char cx[4][50];
clrscr();
printf("Please input 4 integers:");
for(i=0;i<4;i++)
scanf("%f",&num[i]);
for(i=0;i<4;i++)
{
sprintf(cx[i],"%d",(int)num[i]);
}
fun(num,cx,4);
printf("no answer!");
getch();
}
30 楼
yczni [专家分:340] 发布于 2004-06-02 13:31:00
顶
我来回复