习题7-13:数字表达式

来源:互联网 发布:linux把ip写入配置文件 编辑:程序博客网 时间:2024/06/05 08:45

习题7-13:数字表达式
题意:
给定一个数字,可以在中间插入+ - * 使得式子等于2000.
思路:
暴力枚举,最多8个位置,每个位置有4种情况,最多4^8。 可行。不过要注意题目中要按字典序输出,还有一个坑点,就是至少要插入一个运算符,所以2000=是IMPOSSIBLE。
(还涉及中缀表达式转后缀表达式)

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<string>#include<cmath>#include<set>#include<queue>#include<map>#include<stack>#include<vector>#include<list>#include<deque>using namespace std;typedef long long ll;const int maxn = 1e6 + 10;const double eps = 1e-6;const int INF = 1 << 30;string s;char ant[5] = " +-*";set<string>answer;bool flag;int num[15], d;string ans;bool judge(int n){    ans.clear();    for(int i = 0; i < n; i++)    {        ans += s[i];        if(num[i])        {            ans += ant[num[i]];        }    }    ans += s[n];    ///四则运算表达式模板    string ans2;    stack<char>sign;    int q[15];    int tot = 0, sum = 0;    for(int i = 0; i < ans.size(); i++)    {        if(isdigit(ans[i]))sum++;        else {q[tot++] = sum;sum = 0;}    }    q[tot++] = sum;    for(int i = 0; i < ans.size(); i++)    {        if(isdigit(ans[i]))ans2 += ans[i];        else        {            if(sign.empty())sign.push(ans[i]);            else            {                if(ans[i] == '*')                {                    while(1)                    {                        if(sign.empty() || sign.top() != '*'){sign.push(ans[i]); break;}                        ans2 += sign.top();                        sign.pop();                    }                }                else                {                    while(!sign.empty())                    {                        ans2 += sign.top();                        sign.pop();                    }                    sign.push(ans[i]);                }            }        }    }    while(!sign.empty())ans2 += sign.top(), sign.pop();    //for(int i = 0; i < tot; i++)cout<<q[i]<<" ";    tot = 0;    sum = 0;    int a, b;    stack<int>took;  // cout<<ans<<"   "<<ans2<<endl;    for(int i = 0; i < ans2.size(); i++)    {        if(isdigit(ans2[i]))        {            for(int j = i; j < i + q[tot]; j++)            {                if(j == i && q[tot] > 1 && ans2[j] == '0')return false;                sum = sum * 10 + ans2[j] - '0';            }            i = i + q[tot++] - 1;            took.push(sum);            sum = 0;        }        else        {            a = took.top();            //cout<<"a"<<a<<endl;            took.pop();            b = took.top();            //cout<<"b"<<b<<endl;            took.pop();            if(ans2[i]=='*')took.push(a * b);            if(ans2[i]=='+')took.push(a + b);            if(ans2[i]=='-')took.push(b - a);        }    }    //cout<<took.top()<<endl;    if(took.top() == 2000)    {        //for(int i = 0; i < tot; i++)cout<<q[i]<<" ";       // cout<<ans2<<"     "<<ans<<endl;        return true;    }    return false;}void dfs(int n){    if(n == d - 2)    {        if(judge(n))        {            flag = 1;            ans += "=";            answer.insert(ans);            //cout<<ans<<endl;        }        return ;    }    for(int i = 0; i < 4; i++)    {        num[n] = i;        dfs(n + 1);        num[n] = 0;    }}int main(){    int cases = 0;    while(cin >> s)    {        if(s == "=")break;        printf("Problem %d\n", ++cases);        if(s == "2000=")///特判,必须插入符号        {            printf("  IMPOSSIBLE\n");            continue;        }        d = s.size();        answer.clear();        flag = 0;        dfs(0);        if(!flag)        {            printf("  IMPOSSIBLE\n");        }        else        {            for(set<string>::iterator it = answer.begin(); it != answer.end(); it++)            {                cout<<"  "<<*it<<endl;;            }        }    }    return 0;}