回 帖 发 新 帖 刷新版面

主题:做了个算24点牌的C程序,另求算“猜数字”思想

先说“猜数字”,是不是最少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 楼

如果要猜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 楼

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 楼

呵呵好热闹哦,``````虽然我看不懂`大家热爱C哦````````````我也想象达到你们这样的程度,来讨论这些!!!大哥多多教教小弟,我会努力学的

24 楼

其实最难猜出的是前两次有一次是0a1b,一次是0a2b;
按21楼的说法最难猜的就是前两次一次是1a0b,一次是2a0b;

25 楼

很久以前我看楼主就是只发了11个贴子,看样子楼主应该有大半年没有来了。

26 楼

感谢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 楼

您猜猜8021和9715,如果思想不变每次都取最小数作为试猜的话还应该有79个数需要8次才能猜中
我的思想和您的相同.
我程序中的特殊的数,是用程序算出的较好的数,但不是最好的数,最好的要继续把类分得更细.
我对c还不太熟,乱说
不知道您是不是用了c99的标准
tc20可能不支持c99,只支持c89

28 楼

to 13楼
因为这个贴子是去年十月发起的早就沉到箱底去了,这个贴子我看到过但是没回,即使回了也没人能看到啊
后来我发现一个贴子只要有人回它就会跑到前面的页,没人回就沉箱底.

29 楼

/*用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 楼

我来回复

您尚未登录,请登录后再回复。点此登录或注册