P3952 [NOIP2017 提高組] 時間複雜度
阿新 • • 發佈:2021-08-25
這題開始想用迴圈做,WA了三發,想得太簡單了,沒有想到有這種情況的巢狀:
F ...
F ...
E
F ...
E
E
所以改用遞迴,dfs()返回下一層的時間複雜度(下一層所有並列的F中複雜度的最大情況)
注意:有一個特殊情況就是在出現F i x y
當x比y要大的時候,這個迴圈(不管他裡面有沒有巢狀)的複雜度一定是1,所以計算完某一個F迴圈的所有子迴圈的複雜度以後,需要特判一下是不是要加到F的複雜度上去
#include<iostream> #include<vector> #include<string> #include<map> using namespace std; int idx = 0; vector<string> v; map<string, int> table; #define ERR -2 void get(string &val, string &l, string &r, string &x, int idx){ while(idx < x.size() && x[idx] == ' ') idx ++; while(idx < x.size() && x[idx] != ' ') val += x[idx ++]; while(idx < x.size() && x[idx] == ' ') idx ++; while(idx < x.size() && x[idx] != ' ') l += x[idx ++]; while(idx < x.size() && x[idx] == ' ') idx ++; while(idx < x.size() && x[idx] != ' ') r += x[idx ++]; } int dfs(int u){ vector<int> comp; // 存一個本層所有for的複雜度序列 string cur_val; int E = 0; int F = 0; while(idx < v.size()){ string t = v[idx]; if(t[0] == 'F'){ if(!E && F){ int ans = dfs(u + 1); if(ans == ERR) return ans; if(~comp.back()) comp.back() += max(ans, 0); continue; } E = 0; F = 1; string val, l, r; get(val, l, r, t, 1); if(table[val]) return ERR; table[val] = 1; cur_val = val; if(l == r) comp.push_back(0); else if(l == "n") comp.push_back(-1); else if(r == "n") comp.push_back(1); else if(stoi(l) <= stoi(r)) comp.push_back(0); else comp.push_back(-1); }else{ if(!F){ if(u) break; else return ERR; } E = 1; F = 0; table[cur_val] = 0; } idx ++; } if(!E) return ERR; int maxv = 0; for(int i = 0; i < comp.size(); i ++) maxv = max(maxv, comp[i]); return maxv; } int main(){ int t; cin >> t; while(t --){ int n; string o; cin >> n >> o; getchar(); v.clear(); for(int i = 0; i < n; i ++){ string t; getline(cin, t); v.push_back(t); } idx = 0; table.clear(); int res = dfs(0); if(res == ERR){ puts("ERR"); continue; } int num = 0; if(o[2] == 'n') for(int i = 4; i < o.size() && o[i] != ')'; i ++) num = num * 10 + o[i] - '0'; if(num == res) puts("Yes"); else puts("No"); } return 0; }