算24点-回溯法

 题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1267
【问题描述】
       几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”。您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24。
       您可以使用的运算只有:+,-,*,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是合法的,2*(2/4)是不合法的)。下面我们给出一个游戏的具体例子:
       若给出的4个操作数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。
【输入】
       只有一行,四个1到9之间的自然数。
【输出】
       如果有解的话,只要输出一个解,输出的是三行数据,分别表示运算的步骤。其中第一行是输入的两个数和一个运算符和运算后的结果,第二行是第一行的结果和一个输入的数据、运算符、运算后的结果;第三行是第二行的结果和输入的一个数、运算符和“=24”。如果两个操作数有大小的话则先输出大的。
       如果没有解则输出“No answer!”
【输入样例】
       1 2 3 7     
【输出样例】
       2+1=3
       7*3=21
       21+3=24

 

代码:(粘贴过来的)

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
bool flag;
int num[4];
struct node
{
    int a,b,sum;//sum存放a,b经过oper运算之后的值 
    char oper;
};
void dfs(int cur,int a,int b,queue  route)
{
    if(flag) return ;
    if(cur==3)//计算收尾 
    {
        if(((a+b)==24)||((a-b)==24)||((a*b)==24)||(b!=0&&a%b==0&&a/b==24)){//如果经过上面的计算得到解 
           while(!route.empty()){
              node now=route.front();
              printf("%d%c%d=%d\n",now.a,now.oper,now.b,now.sum);//依次输出前面的计算过程 
              route.pop();
           }
           if((a+b)==24){
              if(b>a) swap(a,b);
              printf("%d+%d=%d\n",a,b,a+b);
           }
           if((a-b)==24) printf("%d-%d=%d\n",a,b,a-b);
           
           
           if((a*b)==24) {
              if(b>a) swap(a,b);
              printf("%d*%d=%d\n",a,b,a*b);
           }
           if(a%b==0&&b!=0&&(a/b)==24) printf("%d/%d=%d\n",a,b,a/b);//a/b比较特殊,要求结果必须是整数 
           flag=true;//表示找到解,一旦找到任何一个解就退出                                                               
        }
        return ;
    }
    queue  temp=route;
    node x;
    x.a=a,x.b=b,x.sum=a+b,x.oper='+';
    if(b>a) swap(x.a,x.b);
    temp.push(x);
    dfs(cur+1,a+b,num[cur+1],temp);//(((a*b)*c)*d) 模型 

    temp=route;
    x.a=a,x.b=b,x.sum=a*b,x.oper='*';
    if(b>a) swap(x.a,x.b);
    temp.push(x);
    dfs(cur+1,a*b,num[cur+1],temp);

    temp=route;
    x.a=a,x.b=b,x.sum=a-b,x.oper='-';
    temp.push(x);
    dfs(cur+1,a-b,num[cur+1],temp);


    if(b!=0&&a%b==0){//a/b需要验证合法性 
       temp=route;
       x.a=a,x.b=b,x.sum=a/b,x.oper='/';
       temp.push(x);
       dfs(cur+1,a/b,num[cur+1],temp);
    }

    temp=route;
    x.a=b,x.b=num[cur+1],x.sum=b+num[cur+1],x.oper='+';
    if(x.b>x.a) swap(x.a,x.b);
    temp.push(x);
    dfs(cur+1,a,b+num[cur+1],temp);//a*((b*c)*d) 模型 
    
    temp=route;
    x.a=b,x.b=num[cur+1],x.sum=b*num[cur+1],x.oper='*';
    if(x.b>x.a) swap(x.a,x.b);
    temp.push(x);
    dfs(cur+1,a,b*num[cur+1],temp);

    temp=route;
    x.a=b,x.b=num[cur+1],x.sum=b-num[cur+1],x.oper='-';
    temp.push(x);
    dfs(cur+1,a,b-num[cur+1],temp);

    if(num[cur+1]!=0&&b%num[cur+1]==0) {
      temp=route;
      x.a=b,x.b=num[cur+1],x.sum=b/num[cur+1],x.oper='/';
      temp.push(x);
      dfs(cur+1,a,b/num[cur+1],temp);
    }
}
int main()
{
    //freopen("point24.in","r",stdin);//输入输出重定向 
    //freopen("point24.out","w",stdout);
    queue  t;
    scanf("%d %d %d %d",&num[0],&num[1],&num[2],&num[3]);
    while(!flag){
         dfs(1,num[0],num[1],t);
         printf("%d %d %d %d\n",num[0],num[1],num[2],num[3]);
         if(!next_permutation(num,num+4))  break;
    }
    if(!flag) printf("No answer!\n");
    system("pause");
    return 0;
}

你可能感兴趣的:(回溯法)