[NOIp2017] 时间复杂度

洛谷题号:P3952

出处: NOIp2017提高组Day1T2

主要算法:模拟

难度:4.3

思路分析:

       思维难度真是没什么,就是考验代码能力。

  这题由于循环会嵌套,所以用递归来模拟,这也算一个比较坑的模拟吧。基本思想是,当前这一层的复杂度等于这一层的复杂度加上内部复杂度的最大值(可以有多个同一层的for循环)。

代码注意点:

  细节!!!

 

Code

 

/*By QiXingzhi*/
#include <cstdio>
#include <iostream>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
string _time;
string s[110];
int st[110];
int n,T,L,_t,a,b,cnt;
bool var[260];
inline int GetNumber(string a, int x, int y){
    int res = 0;
    for(int i = x; i <= y; ++i){
        res = (res << 3) + (res << 1) + a[i] - '0';
    }
    return res;
}
inline char GetVariable(string w){
    return w[2];
}
inline int GetTimeComplexity(string a){
    int len = a.length();
    if(len == 4) return 0;
    int res = GetNumber(a,4,len-2);
    return res;
}
inline void FoundFromTo(string w, int x){
    a = 0;
    b = 0;
    int p = x;
    if(w[p] == 'n'){
        a = -1;
        ++p;
    }
    else{    
        for(; w[p] != ' '; ++p){
            a = a * 10 + w[p] - '0';
        }
    }
    ++p;
    int limit = w.length()-1;
    if(w[p] == 'n'){
        b = -1;
    }
    else{
        for(; p <= limit; ++p){
            b = b * 10 + w[p] - '0';
        }        
    }
}
inline bool Compile(int sta, int end){
    int pl = 0;
    for(int i = sta; i <= end; ++i){
        if(s[i][0] == 'F'){
            ++pl;
        }
        else if(s[i][0] == 'E'){
            --pl;
        }
    }
    if(pl != 0) return 0;
    memset(var,0,sizeof(var));
    int top = 0;
    for(int i = sta; i <= end; ++i){
        if(s[i][0] == 'F'){
            ++top;
            st[top] = GetVariable(s[i]);
            if(var[st[top]]) return 0;
            var[st[top]] = 1;
        }
        else if(s[i][0] == 'E'){
            --pl;
            var[st[top]] = 0;
            --top;
        }
    }
    return 1;
}
inline int GetTC(string w){
    FoundFromTo(w, 4);
    if(a == -1 && b == -1){
        return 0;
    }
    if(a != -1 && b != -1 && a <= b){
        return 0;
    }
    if(a != -1 && b != -1 && a > b){
        return -1;
    }
    if(a == -1 && b != -1){
        return -1;
    }
    if(a != -1 && b == -1){
        return 1;
    }
}
int CulTC(int sta, int end){
    int Ans = -1;
    if(sta + 1 == end){
        return GetTC(s[sta]);
    }
    int p = sta;
    int q = sta;
    while(1){
        int pl = 0;
        q = p;
        for(; q <= end; ++q){
            if(s[q][0] == 'F'){
                ++pl;
            }
            if(s[q][0] == 'E'){
                --pl;
            }
            if(pl == 0){
                break;
            }
        }
        int res = 0;
        if(p == sta && q == end){
            int tim = GetTC(s[p]);
            int tmp = CulTC(p+1,q-1);
            if(tim == -1){
                Ans = Max(Ans, 0);
            }
            else if(tim == 0){
                if(tmp == -1) tmp = 0;
                Ans = Max(Ans, tmp);
            }
            else{
                if(tmp == -1) tmp = 0;
                Ans = Max(Ans,tim+tmp);
            }
        }
        else{
            int tmp = CulTC(p,q);
            if(tmp == -1) tmp = 0;
            Ans = Max(Ans, tmp);     
        }
        if(q == end) break;
        p = q+1;
    }
    return Ans;
}
int main(){
    cin >> T;
    while(T--){
        cin >> L;
        cin >> _time;
        cin.get();
        _t = GetTimeComplexity(_time);
        for(int i = 1; i <= L; ++i){
            getline(cin, s[i]);
        }
        if(!Compile(1,L)){
            printf("ERR\n");
            continue;
        }
        int tc = CulTC(1,L);
        if(tc == _t){
            printf("Yes\n");
        }
        else printf("No\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qixingzhi/p/9285772.html