1. 程式人生 > 其它 >P3952 [NOIP2017 提高組] 時間複雜度

P3952 [NOIP2017 提高組] 時間複雜度

這題開始想用迴圈做,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;
}