1. 程式人生 > >【luogu P3952 時間復雜度】題解

【luogu P3952 時間復雜度】題解

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 err
8 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 return
num; 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 時間復雜度】題解