題目連結:http://poj.org/problem?id=3295
題目意思:給定你一邏輯運算式,讓你判斷這個式子是不是永真式
這個題目對於有一點ACM基礎的孩子來說都算是比較簡單的一題
但是我卻花了兩小時 wa了數次
原因一:
誤認為題目給的測試資料都會是保證從會面向前取值的時候都會滿足取值到兩個後(N除外)都會有一個邏輯符號等著他們,事實證明我錯了,我wa的傷心死了
後來想到這點,但是不敢確定,就在default上測試那個條件 用個while(1)來測試,如果OJ返回逾時,那麼就說明我的猜想是對的,果然返回逾時;
原因二:
這個錯誤發現的比較快,但是也不明顯,就是switch語句,如果不在case語句後的都不會執行,下面的s--就是,哎呀,不應該啊!
switch(name[len]) { s--;//這個語句永遠都不會執行 case 'K':ch=my_map[rec[s]]&&my_map[rec[s-1]] ? '1' : '0';s--;break; case 'A':ch=my_map[rec[s]]||my_map[rec[s-1]] ? '1' : '0';s--;break; case 'E':ch=my_map[rec[s]]==my_map[rec[s-1]] ? '1' : '0';s--;break; case 'C':ch=(!my_map[rec[s]])||my_map[rec[s-1]] ? '1' : '0';s--;break; case 'N':ch=my_map[rec[s]] ? '0' : '1';break; // default:printf("S:%d\n",s); }
然後就是這個題目解題了,按照正常情況來,類比下棧就搞定了!
我這裡pqr什麼的都用map來對應真值,這樣比較方便!
#include <iostream>#include <stdio.h>#include <map>#include <string.h>using namespace std;char str[200];char temp[200];char rec[200];map<char,bool> my_map;//這個map待會插入的時候注意0 and 1也插入一次bool is_ok(char *name,int len){ char ch; int s=0; len--; while(len>=0) { if(name[len]>='a' && name[len]<='z') { rec[s++]=name[len]; len--; } else { s--; switch(name[len]) { case 'K':ch=my_map[rec[s]]&&my_map[rec[s-1]] ? '1' : '0';s--;break; case 'A':ch=my_map[rec[s]]||my_map[rec[s-1]] ? '1' : '0';s--;break; case 'E':ch=my_map[rec[s]]==my_map[rec[s-1]] ? '1' : '0';s--;break; case 'C':ch=(!my_map[rec[s]])||my_map[rec[s-1]] ? '1' : '0';s--;break; case 'N':ch=my_map[rec[s]] ? '0' : '1';break; } rec[s++]=ch; len--; } } return my_map[rec[0]];}int main(){ int p,q,r,s,t,len; bool flag; while(scanf("%s",str)) { flag=true; len=strlen(str); if(strcmp(str,"0")==0) return 0; for(p=0;p<2 && flag;p++) for(q=0;q<2 && flag;q++) for(r=0;r<2 && flag;r++) for(s=0;s<2 && flag;s++) for(t=0;t<2 && flag;t++) { my_map['0']=false; my_map['1']=true; strcpy(temp,str); my_map['p']=p; my_map['q']=q; my_map['r']=r; my_map['s']=s; my_map['t']=t; if(!is_ok(temp,len)) flag=false; my_map.clear(); } if(flag) printf("tautology\n"); else printf("not\n"); } return 0;}