ZOJ 1145 Dreisam Equations(简单回溯)

During excavations in the Dreisamwuste, a desert on some far away and probably uncivilized planet, sheets of paper containing mysterious symbols had been found. After a long investigation, the project scientists have concluded that the symbols might be parts of equations. If this were true, it would be proof that the Dreisamwuste was civilized a long long time ago.

The problem, however, is that the only symbols found on the sheets are digits, parantheses and equality signs. There is strong evidence that the people living in the Dreisamwuste knew only of three arithmetic operations: addition, subtraction, and multiplication. It is also known that the people of the Dreisamwuste did not have prioritization rules for arithmetic operations - they evaluate all terms strictly left to right. For example, for them the term 3 + 3 * 5 would be equal to 30, and not 18.

But currently, the sheets do not contain any arithmetic operators. So if the hypothesis is true, and the numbers on the sheets form equations, then the operators must have faded away over time.

You are the computer expert who is supposed to find out whether the hypothesis is sensible or not. For some given equations (without arithmetic operators) you must find out if there is a possibility to place +, -, and * in the expression, so that it yields a valid equation. For example, on one sheet, the string ``18=7 (5 3) 2" has been discovered. Here, one possible solution is ``18=7+(5-3)*2". But if there was a sheet containing ``5=3 3", then this would mean that the Dreisamwuste people did not mean an equation when writing this.


Input

Each equation to deal with occupies one line in the input. Each line begins with a positive integer (less than 230) followed by an equality sign =. (For your convenience, the Dreisamwuste inhabitants used equations with trivial left sides only.) This is followed by up to 12 positive integers forming the right side of the equation. (The product of these numbers will be less than 230.) There might be some parentheses around groups of one or more numbers. There will be no line containing more than 80 characters. There is no other limit for the amount of the parentheses in the equation. There will always be at least one space or parenthesis between two numbers, otherwise the occurrence of white space is unrestricted.

The line containing only the number 0 terminates the input, it should not be processed.


Output

For each equation, output the line ``Equation #n:", where n is the number of the equation. Then, output one line containing a solution to the problem, i. e. the equation with the missing +, -, and * signs inserted. Do not print any white space in the equation.

If there is no way to insert operators to make the equation valid, then output the line ``Impossible".

Output one blank line after each test case.


Sample Input

18 = 7 (5 3) 2
30 = 3 3 5
18 = 3 3 5
5 = 3 3
0


Sample Output

Equation #1:
18=7+(5-3)*2

Equation #2:
30=3+3*5

Equation #3:
Impossible

Equation #4:
Impossible


Source: Mid-Central European Regional Contest 1999

#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define mod 1e9+7
#define ll long long
#define maxn 250
#define MAX 500005
#define ms memset
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000") ///在c++中是防止暴栈用的
///2,3,4分别代表加号,减号,乘号
char  exs[maxn];
bool  isnum(char c) { return c<='9'&&c>='0';  }
int i,ans;
int num[maxn],cntn=0;///数字栈
int op[maxn],cntc=0;
int imposs;
int finalop;
int len;///表达式的长度
/*
题目大意:给定一串字符,
要求添加三种运算符号,使得等式成立,
并输出最后成立的结果等式,按题目要求
括号不影响顺序,这下运算就没那么复杂了。

本以为是水题,把扩展的位置检索并记录下来,
回溯三种运算符,时间复杂度为O(3^n),
回溯最后的结果直接再填回原来的表达式中即可。

最后的最后,这题还是没过,不知道哪里出错了,
请高手指点

*/
bool compute()
{
    ///现有num数组,和符号数组。
    int sum=num[0];
    int index=1;
    for(int i=0;i<cntc;i++)
    {
        if(op[i]==-1||op[i]==1) continue;
        switch(op[i])
        {
           case 2:
               sum+=num[index++];
              break;
           case 3:
               sum-=num[index++];
               break;
           case 4:
               sum*=num[index++];
               break;
        }
    }
    return sum==ans;
}
char trans(int x)
{
    if(x==2) return '+';
    if(x==3) return '-';
    if(x==4) return '*';
}

void output()
{
    int opstack[maxn],t=0;
    for(int i=0;i<cntc;i++)
        if(op[i]>1) opstack[t++]=op[i];
    int j=0;
    for(int i=finalop;i<len;i++)
        if(exs[i]==' ')  exs[i]=trans(opstack[j++]);

    printf("%d=%s\n",ans,exs+finalop);
}

void dfs(int t)
{
    if( imposs ) return ;
    while( op[t] ) t++;
    if( t >= cntc )
    {
       if(compute()) ///输出
       {
          imposs=1;
          output();
       }
       return ;
     }
   op[t]=2;
   dfs(t+1);
   op[t]=3;
   dfs(t+1);
   op[t]=4;
   dfs(t+1);
}

void getans()
{
    ans=0,i=0;
    while( isnum(exs[i]) )
    {
        ans=ans*10+exs[i]-'0';
        i++;
    }
    i+=3;
    finalop=i;///记录要输出的位置
}

void read()
{
    len=strlen(exs);
    cntn=0,cntc=0;///初始化
    while(i<len)
    {
        if(isnum(exs[i]))
        {
           int tp=0;
           while(isnum(exs[i]))
           {
              tp=10*tp+exs[i]-'0';
              i++;
           }
           num[cntn++]=tp;
        }

        if(exs[i]==' ')   op[cntc++]=0;
        else if(exs[i]=='(')   op[cntc++]=-1;
        else if(exs[i]==')')   op[cntc++]=1;
        i++;
    }
}

int main()
{
    int ca=0;
    while(gets(exs) && strchr(exs,'='))
    {
        cntn=cntc=0;
        memset(op,0,sizeof(op));
        memset(num,0,sizeof(num));
       getans();
       read();
        imposs=0;
       // for(int k=0;k<cntc;k++) cout<<op[k]<<" ";puts("");
        //for(int k=0;k<cntn;k++) cout<<num[k]<<" ";puts("");
        printf("Equation #%d:\n",++ca);
        dfs(0);///枚举符号位
        if(imposs==0) puts("Impossible");
        puts("");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37451344/article/details/81140702
ZOJ