11108:Problem D: Tautology
問題文
http://uva.onlinejudge.org/external/111/11108.html
WFFという文法が与えられる。以下のようなものだ。
1.p,q,r,s,tはWFFである。
2.WFFである文字列をwとおくと、NwはWFFである。
3.WFFである文字列二つをw,xとおくと、Kwx,Awx,Cwx,EwxはWFFである。
1~3の文字列の操作は以下のルールに従う。
{p,q,r,s,t}=true,false
Kwx = w & x, Awx = w | x, Nw = !w
Cwx = !( w == true && x == false ), Ewx = ( w == x )
文字列が一行ずつ与えられる。その文字列に含まれるp,q,r,s,tがどのような値の取り方をしてもWFFが真になるならtautology,一つでも真にならないような値の取り方があるならnotを出力せよ。
構文解析+全探索。構文解析は書いてある通りにやるだけ。あとはビットでp,q,r,s,tそれぞれの値を決めて2^5回構文解析する。
#include<iostream> #include<string> #include<algorithm> #include<cctype> using namespace std; int now,wwf; string s; bool rec(){ if(now>=s.size())return true; if(isupper(s[now])){ if(s[now]=='K'){ now++; bool res1=rec(); now++; bool res2=rec(); return res1&res2; } else if(s[now]=='A'){ now++; bool res1=rec(); now++; bool res2=rec(); return res1|res2; } else if(s[now]=='N'){ now++; return !rec(); } else if(s[now]=='C'){ now++; bool w=rec(); now++; bool x=rec(); return !(w== true && x==false); } else if(s[now]=='E'){ now++; bool w=rec(); now++; bool x=rec(); return (w==x); } } else { if(s[now]=='p')return (wwf>>4)&1; if(s[now]=='q')return (wwf>>3)&1; if(s[now]=='r')return (wwf>>2)&1; if(s[now]=='s')return (wwf>>1)&1; if(s[now]=='t')return (wwf>>0)&1; } } int main(void){ while(getline(cin,s)){ if(s=="0")break; for(wwf=0;wwf<(1<<5);wwf++){ now=0; if(!rec()){ cout << "not" << endl; goto end; } } cout << "tautology" << endl; end:; } return 0; }