回 帖 发 新 帖 刷新版面

主题:[讨论]求24点算法

看别人做的24点挺爽的,自己想做,就是不知道算法,哪位高手指点一下.....

回复列表 (共51个回复)

11 楼

没看过~~只用过

12 楼

给个软件来看看嘛,看看它处理的好不好

13 楼

我原来想出个非常简单的方法,用VB就可以简单算的;思路也很简单,另外定义两个运算:\ (-)
a\b  ==  b/a
a(-)b == b-a

外加上+-*/共六个运算符。

4个数字排考虑两个二叉树型:

(1)   o1
       /  \
      o2   o3
     / \   / \
    n1 n2 n3 n4

(2)
        o1
       /  \
      o2  n1
     / \
    o3 n2
   / \
  n3 n4

用两个计算函数算这两种情况,循环4个数的无重复全排(24)乘上3个算符的有重复全排(6^3)。

14 楼

VB.......

15 楼

#include<math.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define EPS  1e-8

#define DIN double  /*或int*/

#define MAX  10    /*或13 */

char strs[12],operator[ ][3]={“+”,“-”,“×”,“÷”}; 

DIN ans(int iop,DIN x,DIN y)

{   switch(iop)

    { case 1 : return x+y; 

      case 2 : return x-y; 

      case 3 : return x*y; 

      case 4 : if(y)if(sizeof(DIN)==sizeof(int)&&(int)x%(int)y==0

                     ||sizeof(DIN)==sizeof(double))return x/y; 

      default: return -1; }

}   

int ok2(DIN x,DIN y)

{   int ix; for(ix=1; ix<=4; ix++)

      if(fabs(ans(ix,x,y)-24)<EPS)return(ix); 

    return(0); 

}   

int ok3(DIN a,DIN b,DIN c)

{   int i,j,k; DIN x[3]; 

    x[0]=a; x[1]=b; x[2]=c; 

    for(i=0; i<3; i++)

    for(j=0; j<3; j++)if(j!=i)

    for(k=0; k<3; k++)if(k!=i && k!=j)

    {   int ix,imid; DIN y; 

        for(ix=1; ix<=4; ix++)

        {   y=ans(ix,x[i],x[j]); if(y<=0)continue; 

            if((imid=ok2(y,x[k]))!=0)

            {    if(i==0)printf(“(%s%s%d)%s%d\n”,strs,operator[ix-1],

                                   (int)x[j],operator[imid-1],(int)x[k]); 

            else if(j==0)printf(“(%d%s%s)%s%d\n”,(int)x[i],operator[ix-1],

                                    strs,operator[imid-1],(int)x[k]); 

            else if(k==0)printf(“(%d%s%d)%s%s\n”,(int)x[i],operator[ix-1],

                                    (int)x[j],operator[imid-1],strs); 

               return(1); 

            }  

        }   

    }   return(0); 

}   

int point24(int p[4])

{   int a,b,c,d,i,ix; DIN y; 

    for(a=0; a<4; a++)

    for(b=0; b<4; b++)if(b!=a)

    for(c=0; c<4; c++)if(c!=a && c!=b)

    for(d=0; d<4; d++)if(d!=a && d!=b && d!=c)

        for(ix=1; ix<=4; ix++)

        {  y=ans(ix,p[a],p[b]); if(y<=0)continue; 

           strs[0]=‘(’;  itoa(p[a],&strs[1],10); 

           strcat(strs,operator[ix-1]); i=strlen(strs); 

           itoa(p[b], &strs[i],10); i=strlen(strs); 

           strs[i]=‘)’; strs[i+1]=‘\0’; 

           if(ok3(y,p[c],p[d]))return(1); 

        }  return(0); 

} /* itoa(p[a],&strs[1],10)将p[a]的值按10进制转换成字符串存入&strs[1]*/

main( )

{    int p[4],total,cannot; printf(“4 cards: ”); 

     scanf(“%d%*c%d%*c%d%*c%d”,p,p+1,p+2,p+3); 

     point24(p); 

  /************以下做全面检测********************************************

     total=0; cannot=0; 

     for(p[0]=  1 ; p[0]<=MAX; p[0]++)

     for(p[1]=p[0]; p[1]<=MAX; p[1]++)

     for(p[2]=p[1]; p[2]<=MAX; p[2]++)

     for(p[3]=p[2]; p[3]<=MAX; p[3]++)

     { total++; if(!point24(p)){ cannot++; 

       printf(“%d,%d,%d,%d\n”,p[0],p[1],p[2],p[3]); }

     } printf(“MAX=%d,TOTAL=%d,CANNOT=%d\n”,MAX,total,cannot); 

  ***********************************************************************/



16 楼

到底有些什么算法~~给点思路撒.....

17 楼

请高手赐教哦.....

18 楼

我写过一个死算的,因为所以情况就只有4的4次方再乘以4的阶.情况不多,再加上有同解的情况,所以算出结果用不了多长时间.

19 楼

如果用C,二叉树,我的那个方法可以简化树型,不然还有其它三个,共五个,做遍历没这方便,定义算符,搜索这两棵树,OK了,外写一个输出过程。。。

20 楼

[quote]我原来想出个非常简单的方法,用VB就可以简单算的;思路也很简单,另外定义两个运算:\ (-)
a\b  ==  b/a
a(-)b == b-a

外加上+-*/共六个运算符。

4个数字排考虑两个二叉树型:

(1)   o1
       /  \
      o2   o3
     / \   / \
    n1 n2 n3 n4

(2)
        o1
       /  \
      o2  n1
     / \
    o3 n2
   / \
  n3 n4

用两个计算函数算这两种情况,循环4个数的无重复全排(24)乘上3个算符的有重复全排(6^3)。[/quote]

偶当初第一次做的时候就是用的这种方法,这种方法需要定义6种运算(就是加减乘除加上反向的减和除)
这个偶早在初二已经用VB实现过,不过在去重复解的能力还不够好,需要写大量的代码--

我来回复

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