题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=182
题意:给定一个表达式,可能有几种运算(可能带括号),让你求一个不带括号的等价表达式。
运算符 对应C++中的操作符
!(取反) !
||(或) ||
&(与) &&
<=>(相等) ==
=>(包含) <=(小于等于)
# ^(异或)
对于符号的优先级:() > ! > & > 其他。对于其他运算符,优先级相等,也就是遵循从左到右的运算法则。
思路:字母出现最多10种,暴力枚举每种的取值。对于每一种,结果为0忽视;结果为1,取值为1的直接与(&),取值为0的与非(&!)。想问题要注意转换角度。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define u32 unsigned int
#define u64 unsigned long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))
#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define DOW0(i,x) for(i=x;i>=0;i--)
#define DOW1(i,x) for(i=x;i>=1;i--)
#define DOW(i,a,b) for(i=a;i>=b;i--)
using namespace std;
void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%I64d",&x);}
void RD(u32 &x){scanf("%u",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(i64 &x,i64 &y){scanf("%I64d%I64d",&x,&y);}
void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(i64 &x,i64 &y,i64 &z){scanf("%I64d%I64d%I64d",&x,&y,&z);}
void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
void RD(string &s){cin>>s;}
void PR(int x) {printf("%d\n",x);}
void PR(i64 x) {printf("%I64d\n",x);}
void PR(u32 x) {printf("%u\n",x);}
void PR(double x) {printf("%.4lf\n",x);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
void PR(string x) {cout<<x<<endl;}
bool Q[7][7]={
{0,1,1,1,1,1,0},
{0,1,1,1,1,1,0},
{0,0,1,1,1,1,0},
{0,0,1,1,1,1,0},
{0,0,1,1,1,1,0},
{0,0,1,1,1,1,0},
{1,1,1,1,1,1,1}};
string a,b;
int p[15],q[15];
stack<int> num,op;
void pop()
{
int t=op.top(),x,y;
op.pop();
if(t==0)
{
x=num.top();num.pop();
num.push(!x);
}
else
{
y=num.top();num.pop();
x=num.top();num.pop();
if(t==1) x=x&y;
else if(t==2) x=x||y;
else if(t==3) x=!(x&&!y);
else if(t==4) x=(x==y);
else if(t==5) x=x^y;
num.push(x);
}
}
void cal()
{
while(!num.empty()) num.pop();
while(!op.empty()) op.pop();
int i,t;
for(i=0;i<b.length();i++)
{
if(b[i]>='a'&&b[i]<='j') num.push(q[b[i]-'a']);
else if(b[i]==')')
{
while(op.top()!=6) pop();
op.pop();
}
else
{
t=b[i]-'0';
while(!op.empty()&&op.top()!=6&&Q[op.top()][t])
pop();
op.push(t);
}
}
while(!op.empty()) pop();
if(!num.top()) return;
if(a.length()>0) a+="||";
int flag=0;
for(i=0;i<10;i++) if(p[i])
{
if(flag) a+='&';
if(q[i]==1) a+=(i+'a');
else a+='!',a+=(i+'a');
flag=1;
}
}
void DFS(int dep)
{
if(dep==10)
{
cal();
return;
}
if(!p[dep])
{
DFS(dep+1);
return;
}
q[dep]=1; DFS(dep+1);
q[dep]=0; DFS(dep+1);
}
void deal()
{
a="";
DFS(0);
int i;
if(a.length()>0) cout<<a<<endl;
else
{
for(i=0;i<10;i++) if(p[i])
{
printf("%c&!%c\n",i+'a',i+'a');
return;
}
}
}
int main()
{
cin>>a;
b="";
int i;
for(i=0;i<a.length();i++)
{
if(a[i]>='a'&&a[i]<='j') b+=a[i],p[a[i]-'a']=1;
else if(a[i]=='!') b+='0';
else if(a[i]=='&') b+='1';
else if(a[i]=='|')
{
b+='2';
i++;
}
else if(a[i]=='=')
{
b+='3';
i++;
}
else if(a[i]=='<')
{
b+='4';
i+=2;
}
else if(a[i]=='#') b+='5';
else if(a[i]=='(') b+='6';
else if(a[i]==')') b+=a[i];
}
deal();
return 0;
}