【luogu P3952 時間復雜度】題解
阿新 • • 發佈:2018-02-25
cstring change tar turn algorithm pop names bsp tac
對於2017 D1 T2 這道題
實實在在是個碼力題,非常考驗耐心。
其實大體的思路並不是非常難想出來,但是要註意的小細節比較多。
題目鏈接:https://www.luogu.org/problemnew/show/P3952
思路
對於每一個程序,先讀入L和O(),並將其中的時間復雜度摳出來。
其次整行讀入字符串,即所給定的程序。
判斷第一個字符是F or E
F i x y 需要把x y拿出來,把i壓進棧
E 退棧 壓進i後為了方便退棧及退棧時判斷,用一個flag標記
每做完一個程序,與前面摳出來的時間復雜度對比判斷yesnoerr即可。
註意
1.我的readx和ready函數比較暴力,直接截取常數和n可能存在的位置並保存。所以在考慮情況時,常數與n的位置不能搞錯,也不能少考慮。
2.在每搞完一個程序時,要把初始值和標記都初始化一遍。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <stack> 6 using namespace std; 7 int L,t,anso,codeo;//anso=0 O(1) anso=x O(n^x) 輸入給的時間復雜度 codeo 自己算的時間復雜度 if anso==codeo yes else no if codeo==-1 err8 string code[105];//按行輸入所給代碼(F,E) 9 string ans;//讀入給定的復雜度 O() 10 int readx(string x) 11 { 12 int num; 13 if(x[4] >= ‘0‘ && x[4] <= ‘9‘) num = x[4]-‘0‘; 14 if(x[5] >= ‘0‘ && x[5] <= ‘9‘) num = (x[4]-‘0‘)*10+x[5]-‘0‘; 15 if(x[4] == ‘n‘) num = 1000000; 16 returnnum; 17 } //摳出給定的復雜度 x 18 int ready(string x) 19 { 20 int num; 21 if(x[6] >= ‘0‘ && x[6] <= ‘9‘ && x[7] <= ‘0‘ || x[7] >= ‘9‘) num = x[6]-‘0‘; 22 if(x[7] >= ‘0‘ && x[7] <= ‘9‘ && x[8] <= ‘0‘ || x[8] >= ‘9‘) num = x[7]-‘0‘; 23 if(x[6] >= ‘0‘ && x[6] <= ‘9‘ && x[7] >= ‘0‘ && x[7] <= ‘9‘) num = (x[6]-‘0‘)*10+x[7]-‘0‘; 24 if(x[7] >= ‘0‘ && x[7] <= ‘9‘ && x[8] >= ‘0‘ && x[8] <= ‘9‘) num = (x[7]-‘0‘)*10+x[8]-‘0‘; 25 if(x[6] == ‘n‘) num = 1000000; 26 if(x[7] == ‘n‘) num = 1000000; 27 return num; 28 }//摳出給定的復雜度 y 29 int check1() 30 { 31 int res; 32 if(ans[2] == ‘1‘) res = 0; 33 if(ans[2] == ‘n‘) 34 { 35 if(ans[4]<=‘9‘ && ans[4]>=‘0‘) 36 res = ans[4]-‘0‘; 37 if(ans[5]<=‘9‘ && ans[5]>=‘0‘) 38 res = (ans[4]-‘0‘)*10 + ans[5]-‘0‘; 39 }//記錄輸入給的復雜度 40 return res; 41 } 42 int check2() 43 { 44 stack<int> s; 45 int flag=-1;//標記 46 bool fe[26]={0};//上面都是便於棧操作,fe來記錄變量名 47 int res=0,now=0;//now來記錄當前循環中的時間復雜度,res是整個程序的時間復雜度 48 bool cflag[26]={0};//記錄變量是否重復 0 則沒用過 1 用過 changeflag 49 int xnum,ynum; 50 51 for(int i=1;i<=L;i++) 52 { 53 54 if(code[i][0]==‘F‘) 55 { 56 int k=code[i][2]-‘a‘; 57 if(cflag[k]) return -1; 58 s.push(k); 59 cflag[k] = 1; 60 61 xnum=readx(code[i]); ynum=ready(code[i]); 62 if(ynum-xnum>1000) 63 { 64 if(flag==-1) 65 { 66 now++; 67 res=max(res,now); 68 fe[k]=1; 69 } 70 } 71 if(xnum>ynum) 72 { 73 if(flag==-1) flag=k; 74 } 75 } 76 77 if(code[i][0]==‘E‘) 78 { 79 if(s.empty()) return -1; 80 int k=s.top(); 81 s.pop();cflag[k]=false; 82 if(flag==k) flag=-1; 83 if(fe[k]) 84 { 85 fe[k]=false; 86 now--; 87 } 88 } 89 } 90 if(s.size()) return -1; 91 return res; 92 } 93 int main() 94 { 95 scanf("%d",&t); 96 while(t--) 97 { 98 99 scanf("%d ",&L);getline(cin,ans); 100 anso=check1(); 101 102 for(int i=1;i<=L;i++)getline(cin,code[i]); 103 codeo=check2(); 104 105 if(codeo==-1) cout<<"ERR"<<endl; 106 else 107 { 108 if(anso!=codeo) cout<<"No"<<endl; 109 if(anso==codeo) cout<<"Yes"<<endl; 110 } 111 } 112 return 0; 113 }
【luogu P3952 時間復雜度】題解