回 帖 发 新 帖 刷新版面

主题:做了个算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个回复)

51 楼

我现在的平均步数只有5.270步多一点,不知道现在对猜数字的最好研究是怎样的,麻烦大家在网上搜搜看看有没有,平均步数比我做得结果更好的.

52 楼


Please Enter 4 nums(1~13):
1 2 3 4
(( 1 +  2) +  3) *  4 =24
(( 1 *  2) *  3) *  4 =24
( 1 *  2) * ( 3 *  4) =24
4 / (( 1 /  2) /  3) =24
( 3 / ( 1 /  2)) *  4 =24
(( 1 *  2) *  4) *  3 =24
( 1 *  2) * ( 4 *  3) =24
3 / (( 1 /  2) /  4) =24
( 4 / ( 1 /  2)) *  3 =24
(( 1 +  3) +  2) *  4 =24
( 1 +  3) * ( 2 +  4) =24
(( 1 *  3) *  2) *  4 =24
( 1 *  3) * ( 2 *  4) =24
4 / (( 1 /  3) /  2) =24
( 2 / ( 1 /  3)) *  4 =24
( 1 +  3) * ( 4 +  2) =24
(( 1 *  3) *  4) *  2 =24
( 1 *  3) * ( 4 *  2) =24
2 / (( 1 /  3) /  4) =24
( 4 / ( 1 /  3)) *  2 =24
(( 1 *  4) *  2) *  3 =24
( 1 *  4) * ( 2 *  3) =24
3 / (( 1 /  4) /  2) =24
( 2 / ( 1 /  4)) *  3 =24
(( 1 *  4) *  3) *  2 =24
( 1 *  4) * ( 3 *  2) =24
2 / (( 1 /  4) /  3) =24
( 3 / ( 1 /  4)) *  2 =24
(( 2 +  1) +  3) *  4 =24
(( 2 *  1) *  3) *  4 =24
( 2 *  1) * ( 3 *  4) =24
(( 2 /  1) *  3) *  4 =24
( 2 /  1) * ( 3 *  4) =24
(( 2 *  1) *  4) *  3 =24
( 2 *  1) * ( 4 *  3) =24
(( 2 /  1) *  4) *  3 =24
( 2 /  1) * ( 4 *  3) =24
(( 2 +  3) +  1) *  4 =24
(( 2 *  3) *  1) *  4 =24
( 2 *  3) * ( 1 *  4) =24
(( 2 *  3) /  1) *  4 =24
( 2 *  3) / ( 1 /  4) =24
( 2 *  3) * ( 1 /  4) =24
4 / ( 1 / ( 2 *  3)) =24
(( 2 *  3) *  4) *  1 =24
( 2 *  3) * ( 4 *  1) =24
(( 2 *  3) *  4) /  1 =24
( 2 *  3) * ( 4 /  1) =24
( 2 *  3) / ( 4 /  1) =24
( 2 +  4) * ( 1 +  3) =24
(( 2 *  4) *  1) *  3 =24
( 2 *  4) * ( 1 *  3) =24
(( 2 *  4) /  1) *  3 =24
( 2 *  4) / ( 1 /  3) =24
( 2 *  4) * ( 1 /  3) =24
3 / ( 1 / ( 2 *  4)) =24
( 2 +  4) * ( 3 +  1) =24
(( 2 *  4) *  3) *  1 =24
( 2 *  4) * ( 3 *  1) =24
(( 2 *  4) *  3) /  1 =24
( 2 *  4) * ( 3 /  1) =24
( 2 *  4) / ( 3 /  1) =24
(( 3 +  1) +  2) *  4 =24
( 3 +  1) * ( 2 +  4) =24
(( 3 *  1) *  2) *  4 =24
( 3 *  1) * ( 2 *  4) =24
(( 3 /  1) *  2) *  4 =24
( 3 /  1) * ( 2 *  4) =24
( 3 +  1) * ( 4 +  2) =24
(( 3 *  1) *  4) *  2 =24
( 3 *  1) * ( 4 *  2) =24
(( 3 /  1) *  4) *  2 =24
( 3 /  1) * ( 4 *  2) =24
(( 3 +  2) +  1) *  4 =24
(( 3 *  2) *  1) *  4 =24
( 3 *  2) * ( 1 *  4) =24
(( 3 *  2) /  1) *  4 =24
( 3 *  2) / ( 1 /  4) =24
( 3 *  2) * ( 1 /  4) =24
4 / ( 1 / ( 3 *  2)) =24
(( 3 *  2) *  4) *  1 =24
( 3 *  2) * ( 4 *  1) =24
(( 3 *  2) *  4) /  1 =24
( 3 *  2) * ( 4 /  1) =24
( 3 *  2) / ( 4 /  1) =24
(( 3 *  4) *  1) *  2 =24
( 3 *  4) * ( 1 *  2) =24
(( 3 *  4) /  1) *  2 =24
( 3 *  4) / ( 1 /  2) =24
( 3 *  4) * ( 1 /  2) =24
2 / ( 1 / ( 3 *  4)) =24
(( 3 *  4) *  2) *  1 =24
( 3 *  4) * ( 2 *  1) =24
(( 3 *  4) *  2) /  1 =24
( 3 *  4) * ( 2 /  1) =24
( 3 *  4) / ( 2 /  1) =24
(( 4 *  1) *  2) *  3 =24
( 4 *  1) * ( 2 *  3) =24
(( 4 /  1) *  2) *  3 =24
( 4 /  1) * ( 2 *  3) =24
(( 4 *  1) *  3) *  2 =24
( 4 *  1) * ( 3 *  2) =24
(( 4 /  1) *  3) *  2 =24
( 4 /  1) * ( 3 *  2) =24
( 4 +  2) * ( 1 +  3) =24
(( 4 *  2) *  1) *  3 =24
( 4 *  2) * ( 1 *  3) =24
(( 4 *  2) /  1) *  3 =24
( 4 *  2) / ( 1 /  3) =24
( 4 *  2) * ( 1 /  3) =24
3 / ( 1 / ( 4 *  2)) =24
( 4 +  2) * ( 3 +  1) =24
(( 4 *  2) *  3) *  1 =24
( 4 *  2) * ( 3 *  1) =24
(( 4 *  2) *  3) /  1 =24
( 4 *  2) * ( 3 /  1) =24
( 4 *  2) / ( 3 /  1) =24
(( 4 *  3) *  1) *  2 =24
( 4 *  3) * ( 1 *  2) =24
(( 4 *  3) /  1) *  2 =24
( 4 *  3) / ( 1 /  2) =24
( 4 *  3) * ( 1 /  2) =24
2 / ( 1 / ( 4 *  3)) =24
(( 4 *  3) *  2) *  1 =24
( 4 *  3) * ( 2 *  1) =24
(( 4 *  3) *  2) /  1 =24
( 4 *  3) * ( 2 /  1) =24
( 4 *  3) / ( 2 /  1) =24

我试着运行了一下,里面有些是不成立的?
就如( 4 *  3) / ( 2 /  1) =24,
你找一下,
还有很多也不正确啊

53 楼

yczni,你好
我原来自己学过些c和c++,所以它们的语法我都看得懂,现在想用C#来做一个猜数字的算法工具
已经几天了,没有做出必然能在8步内猜出的算法,不知道你的新算法是什么样的,可以给出来学习一下吗?
我大概想的猜法是,保存几个对象,记录10个数字分别可能出现的概率和四个位置是哪个数字的概率,还有保存可能包含哪四个数字的概率
这样交叉对比几次应该可以比较快地猜到被猜数
可惜已经对算法的研究比较差,现在没有实现我的想法,呵呵,也不知道可行不

54 楼

我研究猜数字的解题程序已有一年多了,有了一点结果,在这里发表一下,希望有兴的朋友顶一下,先谢谢大家了.
  现在网上有两类猜数字,一类是手机答题,或是李勇经常用的游戏,就是一个人猜,李勇还说是大了还是小了.我对这类猜数字不敢兴趣,我研究的是另一类猜数字,是文曲星随机产生一个数由玩家猜,玩家猜一个数文曲星会说出几A几B,大家可以在网上搜到这个游戏的各种版本和具体的玩法.我的任务就是做一个程序让电脑来猜文曲星随产生的数.
  从0123456789十个数字选出四个做一个排列共有5040种方法,我的任务是无论对方想什么数我都能用尽可能少的步数把它猜出来.
  我第一步习惯猜0123,如果你想让我猜的话,你想的那个数千万别是0123,如果是的话我一步就猜出来了.好了不多说了,说结果吧,这可是一年多的心血呀,本来不想发出来,但是想了想还是发出来吧,放在自己的肚子里不会有人知道.
  
第一步猜出:1
第二步猜出:5
第三步猜出:56
第四步猜出:585
第五步猜出:2421
第六步猜出:1893
第七步猜出:79
平均步数只有5.2649步
六步之内可猜出98.43%
五步之内可猜出60.87%

本来五步猜出率可以到61.3%多,我为了让第七步猜出的数尽可能的少(也可以说让六步的猜出率尽可能的大),所以做了一定的取舍,这是鱼和熊掌的问题.


网上有些软件称自己6步可以猜数所有的数,或者说只要六步就可以帮你搞定,那都是骗人的.我已经证明了,6次是不可能把所有数都猜出来的(也就是说,文曲星以一种方式报出几A几B,你就不可能在六次之内知道文曲星在想什么).

其实这种贴我发了很多,这次的结果是我目前得到的最好结果.
我的努力还没有完成,还在进一步工作中,还在寻找着怎能更快猜出的最佳答案.

我的研究也以由最开始的老算法,走到了新算法,现在我是在做着证明性的研究.

希望大家能多顶一下,我会经常来看此贴,给大家打分.

55 楼

顶一下,想知道算法,呵呵

56 楼


24点牌的程序我也编过.好象不一样啊!
#include <stdio.h >

void main ( )

{int a,b,c,d,m,n,o,p,q,h,j,k,s[4]; float F(float,int,float);char G(int);float x,y,z;
 for (q=0;q<4;q++) scanf("%d",&s[q]);
for (m=0;m<4;m++)
{ a=s[m];
for (n=0;n<4;n++)
{b=s[n];if (n==m) continue;
for (o=0;o<4;o++)
{c=s[o];if (o==m||o==n) continue;
for (p=0;p<4;p++)
{d=s[p];if (p==o||p==m||p==n) continue;
for (h=1;h<5;h++)
{x=F(c,h,d);
for (j=1;j<5;j++)
{y=F(b,j,x);
{for (k=1;k<5;k++)
{z=F(a,k,y);
{if (z==24)
{printf("\n%d%c(%d%c(%d%c%d))=24\n", a,G(k),b,G(j),c,G(h),d);break;}else continue;}}}}}}}}}}
float F(float a,int c,float b)

{float y;
 switch (c)
{case 1: y=a+b;break;
case 2:y=a-b;break;
case 3:y=a*b;break;
case 4: if (b!=0) y=a/b;else y=200;}

 return (y);}

 char G (int u)

 {char w; switch (u)
 {case 1: w='+';break;
case 2:w='-';break;
case 3:w='*';break;
case 4:w='/';}
 return (w);}

57 楼

我是新手!
想要知道猜数字最多几步猜出来,只要把0123,0124,...,9875,9876这5040个数一个一个往你编好的程序里代入不就好了?


我这有一个思路,可能很多大大都知道了,我再说一次不算盗版吧?


1.把0123,0124,...,9875,9876这5040个数字看成一个集合。

2.第一次猜0123,人给出回复,比如1A1B。

3.1A1B说明这个四位数里必须有且仅有一个数字与0或1或2或3相同且位置相同的,同时有且仅有一个数字与0,1,2,3这四个数字之一相同但位置不同。
  将原集合0123,0124,...,9875,9876中与上面要求不符的删除。

4.用集合中剩下的第一个数字0415再猜,给出回复后再重复判断,直到集合中剩下一个数字为止或这在这个过程中出现回复4A0B则结束。

我来回复

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