计算机想一个不重复的四位数,人来猜.每次计算机告诉数也对,位置也对的数的个数和数对但位置不对的个数.
例如计算机想的是3194,人猜的是1234,则计算机输出2 1.
人需要在8次之内猜出来.
编这样的程序很简单,可是问题反过来,人想一个数,让计算机在8次之内猜出来. 这个问题就难的多的多了.
我在大三时候想出了下面的办法:
#include<stdio.h> #include<math.h> #include<time.h> int P[5040][5],record[8][2],T,num=5040,A,B,ans[4],key[4],next,guess[8][4], judgetype[14][3]={{0,0},{0,1},{0,2},{0,3},{0,4},{1,0},{1,1},{1,2},{1,3},{2,0},{2,1},{2,2},{3,0},{4,0}}; void Initiate() { int i,j,k,v,p=0,digital[10]={0}; for(i=0;i<=9;i++) { digital[i]=1; for(j=0;j<=9;j++) { if(digital[j]) continue; digital[j]=1; for(k=0;k<=9;k++) { if(digital[k]) continue; digital[k]=1; for(v=0;v<=9;v++) if(!digital[v]) { P[p][0]=1; P[p][1]=i; P[p][2]=j; P[p][3]=k; P[p][4]=v; p++; } digital[k]=0; } digital[j]=0; } digital[i]=0; } srand((unsigned)(time(NULL))/2); for(i=0;i<4;i++) while(1) { guess[0][i]=rand()%10; for(j=0;j<i;j++) if(guess[0][i]==guess[0][j]) break; if(j==i) break; } for(i=0;i<4;i++) printf("%d ",guess[0][i]); printf(" "); scanf("%d%d",&record[0][0],&record[0][1]); T=0; } void teminate(int b) { if(b) printf("我猜对了!\n"); else printf("你是个骗子!!!\n"); exit(0); } getjudge() { int i,j; A=0;B=0; for(i=0;i<4;i++) for(j=0;j<4;j++) if(ans[i]==key[j]) { B++; break; } for(i=0;i<4;i++) if(ans[i]==key[i]) { A++; B--; } } void exclude() { int i,j; for(i=0;i<4;i++) ans[i]=guess[T][i]; for(i=0;i<5040;i++) { if(P[i][0]==0) continue; for(j=0;j<4;j++) key[j]=P[i][j+1]; getjudge(); if(A!=record[T][0]||B!=record[T][1]) { P[i][0]=0; num--; } else next=i; } } void choose() { int i,j,k; double H=0,Hmax=0; for(i=0;i<5040;i++) if(P[i][0]) break; next=i; for(;i<5040;i++) { H=0; for(k=0;k<4;k++) ans[k]=P[i][k+1]; for(k=0;k<14;k++) judgetype[k][2]=0; for(j=0;j<5040;j++) { if(P[j][0]==0) continue; for(k=0;k<4;k++) key[k]=P[j][k+1]; getjudge(); for(k=0;k<14;k++) if(A==judgetype[k][0]&&B==judgetype[k][1]) judgetype[k][2]++; } for(k=0;k<14;k++) if(judgetype[k][2]==0) continue; else H-=judgetype[k][2]*log(1.0*judgetype[k][2]/num); if(H>Hmax) { Hmax=H; next=i; } } } void main() { int i; Initiate(); while(1) { for(i=0;i<14;i++) if(record[T][0]==judgetype[i][0]&&record[T][1]==judgetype[i][1]) break; if(i==14) teminate(0); if(i==13) teminate(1); exclude(); if(num==0) teminate(0); else if(num!=1) choose(); T++; for(i=0;i<4;i++) guess[T][i]=P[next][i+1]; for(i=0;i<4;i++) printf("%d ",P[next][i+1]); printf(" "); scanf("%d%d",&record[T][0],&record[T][1]); } }