POJ 3295 Tautology
大致题意:
对pqrst五个变量之间进行and, or, not, implies, equals五种逻辑运算,若给出的运算结果是恒为1的就输出tautology,否则输出not
这道题我用了列真值表的方式,因为总共就32种取值方式。
P | Q | R | S | T | 对应值 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 1 | 0 | 2 |
0 | 0 | 0 | 1 | 1 | 3 |
0 | 0 | 1 | 0 | 0 | 4 |
0 | 0 | 1 | 0 | 1 | 5 |
… | … | … | … | … | … |
single[5][32]为pqrst的真值表。//本可以用int来操作,但是我还是太年轻了
令pqrst分别对应single二维数组的下标43210,
下面是完成single初始化的代码
for(int i=0;i<5;i++){//完成single的初始化
single[i].resize(32,1);
for(int j=0;j<32;j++){
if(!(j&(1<<(i))))single[i][j]=0;
}
}
之后定义了各个逻辑运算的操作,因为基本都是复制粘贴,很好写。但是如果直接用and来命名会与库函数命名冲突,出现error: expected unqualified-id before ‘and’ token错误
下面是完整代码
#include <iostream>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <climits>
using namespace std;
typedef long long ll;
vector<bool > single[5];
vector<bool> ord(vector<bool> a,vector<bool> b)
{
for(int i=0;i<32;i++){
a[i]=(a[i]|b[i]);
}
return a;
}
vector<bool> notd(vector<bool> a){
for(int i=0;i<32;i++){
a[i]=!a[i];
}
return a;
}
vector<bool> andd(vector<bool> a,vector<bool> b)
{
for(int i=0;i<32;i++){
a[i]=(a[i]&b[i]);
}
return a;
}
vector<bool> equalsd(vector<bool> a,vector<bool> b)
{
for(int i=0;i<32;i++){
a[i]=(a[i]==b[i]);
}
return a;
}
vector<bool> impliesd(vector<bool> a,vector<bool> b)
{
for(int i=0;i<32;i++){
a[i]=((!a[i])|(b[i]));
}
return a;
}
inline int toInt(char c){
return 4-c+'p';
}
bool is_tau(vector<bool> a){
for(int i=0;i<32;i++){
if(a[i]==0)return 0;
// cout<<a[i]<<endl;
}
return 1;
}
string in;
int find_next(int i){//下一个的头
int k=1;
for(;i<in.size();i++){
if(in[i]>='A'&&in[i]<='Z'&&in[i]!='N'){
k++;
}
else if(in[i]!='N'){
k--;
if(!k)return i+1;
}
}
return i;
}
vector<bool> toLogi(int L,int R){
if(in[L]>='p'&&in[L]<='t'){
vector<bool> c(single[toInt(in[L])]);
return c;
}
int s;
switch(in[L]){
case 'K':
s=find_next(L+1);//
return andd(toLogi(L+1,s-1),toLogi(s,R));
break;
case 'A':
s=find_next(L+1);//
return ord(toLogi(L+1,s-1),toLogi(s,R));
break;
case 'N':
s=find_next(L+1);//
return notd(toLogi(L+1,s-1));
break;
case 'C':
s=find_next(L+1);//
return impliesd(toLogi(L+1,s-1),toLogi(s,R));
break;
case 'E':
s=find_next(L+1);//
return equalsd(toLogi(L+1,s-1),toLogi(s,R));
break;
}
}
int main()
{
for(int i=0;i<5;i++){
single[i].resize(32,1);
for(int j=0;j<32;j++){
if(!(j&(1<<(i))))single[i][j]=0;
}
}
while(cin>>in){
if(in=="0")break;
if(is_tau(toLogi(0,in.size()-1)))
cout<<"tautology"<<endl;
else cout<<"not"<<endl;
}
return 0;
}