【题解】P1575 正误问题
题目传送门。
题意:输入一个字符串形式的逻辑表达式,求值。
解题思路:
- 先将读入的一个个字符串转成数字,方便后面计算。
- 先考虑 error 的情况。
- 共 3 种情况使得表达式不合法,包括:连续的布尔值,连续的与、或运算符,非运算后不是布尔值或非运算符。特判后输出即可。
- 特判 error 同时处理逻辑表达式里的非运算符(非运算符拥有最高的优先级),将其对应的逻辑值转换一下。
- 处理完非运算符后,分批处理“与”和“或”两种运算符。
-
处理完后,输出答案即可。
AC 代码(含有注释):
#include<bits/stdc++.h> using namespace std; const int M(1e3+5); int handle[M],flag[M],ans,tot; string s; signed main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); while(cin>>s){ if(s=="false")handle[++tot]=0; if(s=="true") handle[++tot]=1; if(s=="and") handle[++tot]=3; if(s=="not") handle[++tot]=4; if(s=="or") handle[++tot]=2; } for(register int i(1),last(0);i<=tot;++i){ if(!handle[i]||handle[i]==1){//当前位置是布尔值 if(last==1) {cout<<"error";return 0;}//是否为连续布尔值 last=1; } else{ if(handle[i]==4){//当前位置是非 if(handle[i+1]==2||handle[i+1]==3){ cout<<"error";return 0;//非后跟其他逻辑运算符 } else{ bool ts(1);while(handle[i+1]==4)++i,ts^=1;//处理连续的非 handle[i+1]=ts^handle[i+1]; } } else{ if(!last) {cout<<"error";return 0;}//前面是不是布尔值 last=0; } } } register int top(0); for(register int i(1);i<=tot;++i){ if(!handle[i]||handle[i]==1) ++top,flag[top]=handle[i]; if(handle[i]==3) flag[top]&=handle[++i];//处理与运算 } for(register int i(1);i<=top;++i) ans|=flag[i]; if(!ans)cout<<"false";else cout<<"true"; return 0; }