sgu182:Open the brackets(逆波兰表达式+暴力枚举)

来源:互联网 发布:皇冠接水程序源码论坛 编辑:程序博客网 时间:2024/06/02 14:32
题意:
给出一个逻辑表达式,求出其去掉括号后的等价表达式。
"<=>"="=="
"=>"="<="
"#"="^"
"&"="&&"
其他和普通逻辑表达式一样。
变量有'a'...'j'共10个,每个变量的值为0或1。
输入长度在2048以内,输出长度在32768以内。
分析:
注意:输入长度在2048以内,输出长度在32768以内。
为什么输出长度这么大??摆明了暴力嘛...
枚举每个变量的值,带入计算,如果表达式值为1,输出规则如下:如果此时a=0,输出!a,否则a,两变量之间用&来连接。
两种取值都可以使表达式值为1的中间用"||"隔开。
比如当a=0,b=1,c=0时值为1,当a=1,b=0,c=0时值也为1,那么就是!a&b&!c||a&!b&!c。
为了方便求解,我们可以先转逆波兰表达式,除了"!"从右往左算,其余的双目运算符都是从左往右算。
逆波兰表达式具体计算方式如下:
①当s[i]=='('入栈;
②当s[i]==')'弹出栈中元素直到遇到第一个'(';
③当s[i]为变量,直接弹出;
④当s[i]优先级比栈顶元素高或栈为空,入栈;否则弹出栈顶元素,重复④。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <stack>using namespace std;const int MAXL = 2060;char src[MAXL], str[MAXL], str2[MAXL];int sum, val[30], len, len2;int ml = -1;bool hash[30];int f[250];bool kflag = 0;bool check(){stack<int> num;int tmp, tmp2;for(int i = 0; i < len2; ++i)if(str2[i] >= 'a' && str2[i] <= 'j') num.push(val[str2[i]-'a']);else{tmp = num.top();num.pop();switch(str2[i]){case '!':num.push(tmp^1);break;case '&':tmp2 = num.top();num.pop();num.push(tmp&&tmp2);break;case '|':tmp2 = num.top();num.pop();num.push(tmp||tmp2);break;case '=':tmp2 = num.top();num.pop();num.push(tmp==tmp2);break;case '>':tmp2 = num.top();num.pop();num.push(tmp>=tmp2);break;case '#':tmp2 = num.top();num.pop();num.push(tmp^tmp2);break;}}return num.top();}void print(){bool flag = 0;if(kflag) cout << "||";else kflag = 1;for(int i = 0; i < 26; ++i)if(hash[i]){if(flag) cout << "&";else flag = 1;if(val[i]) cout << (char)(i+'a');else cout << "!" << (char)(i+'a');}}void dfs(int cur){if(cur > ml){if(check())print();return ;}while(!hash[cur]) cur++;val[cur] = 1;dfs(cur+1);val[cur] = 0;dfs(cur+1);}void change(){int j = 0;str[j++] = '(';for(int i = 0, lim = strlen(src); i < lim; ++i)if(src[i] == '<') {str[j++] = '=';i += 2;}else if(src[i] == '='){str[j++] = '>';i++;}else if(src[i] == '|'){str[j++] = '|';i++;}else str[j++] = src[i];str[j++] = ')';len = j;}void change2(){f['!'] = 1, f['&'] = 2, f['|'] = f['='] = f['>'] = f['#'] = 3, f['('] = 4;stack<char> cha;for(int i = 0; i < len; ++i)if(str[i] == '(') cha.push('(');else if(str[i] == ')'){while(cha.top() != '('){str2[len2++] = cha.top();cha.pop();}cha.pop();}else if(str[i] >= 'a' && str[i] <= 'j') str2[len2++] = str[i];else {while(1){if(cha.empty() || (f[(int)cha.top()] > f[(int)str[i]] || (str[i] == '!' && cha.top() == '!'))){cha.push(str[i]);break;}str2[len2++] = cha.top();cha.pop();}}}int main(){cin >> src;change();change2();for(int i = 0; i < len2; ++i)if(str2[i] >= 'a' && str2[i] <= 'j'){   hash[str2[i]-'a'] = 1;ml = max(ml, str2[i]-'a');}dfs(0);if(!kflag) cout << (char)(ml+'a') << "&!" << (char)(ml+'a');return 0;}

0 0
原创粉丝点击