24点 程序

其实这是一道ICM题,即不一定是24点,给定一个自然数集合和一个目标数,求最优解。

慌忙中作答,写在这里为的是以后回来好优化一下。


#include <stdio.h>

 

 

double st[20];

int sp=0;

 

const int COUNT=6;

int numbers[COUNT]={1,2,3,4,7,25};

int answer=573;

int ops[4]={'+','-','*','/'};

 

int buildexp();

void buildnum(int n);

void buildop(int n);

 

inline void push(double i)

{

       st[sp++]=i;

}

 

inline double pop()

{

       return st[--sp];

}

 

inline double op(double a, double b, char c)

{

       switch( c )

       {

               case '+': return a+b; break;

               case '-': return a-b; break;

               case '*': return a*b; break;

               case '/': return a/b; break;

       }

}

 

inline int is_op(char c)

{

       return ((c=='+')||(c=='-')||(c=='*')||(c=='/'));

}

 

double cal(int* exp)

{

       int i=0;

       double x,y;

       while (exp[i])

       {

             if (is_op((char)exp[i]))

             {

                    y=pop();

                    x=pop();

                    //printf("%d %d %d/n",x, ((char)exp[i]), y);

                    push(op(x,y,exp[i]));

             }

             else

             {

                 push((double)exp[i]);

             }

             i++;

       }

       return pop();

}

 

int pos[COUNT-1];

 

void buildmode(int p, int r, int l)

{

   //  printf("%d %d %d/n",p,r,l);

     int i;

     if (r==0)

     {

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

  //       for (i=1;i<=l;i++) printf("%d",pos[i]);

        // printf("/n");

         buildnum(COUNT-1);

 //        getchar();

         return;

     }

 

     for(i=((r>p-1)?(r-p+1):r);i<=((r>p)?p:r);i++)

     {

             pos[p]=i;

             buildmode(p-1, r-i, l);

     }

}

 

void mode(int i)

{

     buildmode(i, i, i);

}

 

int t_num[COUNT]={3,8,3,8};

int t_p[COUNT]={0,0,0,0};

int t_op[COUNT-1];

int t_exp[2*COUNT];

 

void buildnum(int n)

{

     int i;

     if (n<0)

     {

 //        for (i=0;i<COUNT;i++) printf("%d",t_num[i]);

   //      printf("/n");

         buildop(COUNT-1);

         return;

     }

 

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

     {

         if (numbers[i] >0){

             t_num[n]=numbers[i];

             numbers[i]=-numbers[i];

             buildnum(n-1);

             numbers[i]=-numbers[i];

         }

     }

    

}

 

 

void buildop(int n)

{

     int i;

     if (n<0)

     {

         buildexp();

         return;

     }

 

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

     {

             t_op[n]=ops[i];

             buildop(n-1);

     }

}   

 

int buildexp()

{

    int i;

    int j=0;

    t_exp[0]=t_num[0];

    int p=1;

    int p_op=0;

    for (i=1;i<COUNT;i++)

    {

        t_exp[p++]=t_num[i];

        for( j=1; j<=pos[i];j++)

        {

             t_exp[p++]=t_op[p_op++];

        }

    }

    //t_exp[p]=0;

    for(i=0;i<2*COUNT;i++)

    {

        if (is_op(t_exp[i]))

            printf("%c ",t_exp[i]);

        else

            printf("%d ",t_exp[i]);

    }

    printf("=%f",cal(t_exp));

    printf("/n");

    double f= cal(t_exp)-answer;

    f=(f>=0)?f:(-f);

    

   if (f<0.1)

    getchar(); 

}

 

 

int main()

{

     int exp[]={8,3,8,3,'/','-','/',0};

 

     int i,j,k;

     int n=6;

 //    buildnum(COUNT-1);

     mode(COUNT);

     ;

 

     printf("%f",cal(exp));

    

     getchar();

     return 0;

}

            

            

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值