NOIP 2017 时间复杂度

题目链接

https://www.luogu.org/problemnew/show/P3952

去年考试这道题貌似20分

今天又写,怒干1个半小时,一次AC

重点是静下心来,理清思路,知道要干什么

然后慢慢地查错

之后自己造一些比较难的数据来测

这种细节巨多的题就要静下来,就好了

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;

int main()
{
    int T; 
    scanf("%d", &T);
    
    while(T--)
    {
        char s[50]; int L, num = 0, ok = 0;
        scanf("%d%s", &L, s);
        
        REP(i, 0, strlen(s))
        {
            if(isdigit(s[i])) num = num * 10 + s[i] - '0';
            if(s[i] == '^') ok = 1;
        }
        if(!ok) num = 0;
        
        int vis[30];
        memset(vis, 0, sizeof(vis));
        stack<int> st;
        int op = 0, cnt;
        int ans = 0, sum = 0;
        
        gets(s);
        _for(r, 1, L) 
        {
            gets(s); 
            if(ans == -1) continue; //ERR
            
            if(strlen(s) == 1) 
            { 
                if(op == 1 && --cnt == 0) op = 0;
                if(st.empty()) { ans = sum = -1; continue; }
                
                vis[st.top()] = 0; st.pop(); 
                sum = max(sum, ans);
                if(ans) ans--;
            }
            else
            {
                char s1[5], s2[5], s3[5]; 
                int k = 0, cnt1 = 0, cnt2 = 0;
                
                REP(i, 0, strlen(s)) //切下来 
                {
                    if(s[i] == ' ') continue;
                    if(i > 0 && s[i-1] == ' ') k++;
                    if(k == 1) s1[0] = s[i];
                    if(k == 2) s2[cnt1++] = s[i];
                    if(k == 3) s3[cnt2++] = s[i];
                }
            
                int id = s1[0] - 'a';
                if(vis[id]) { ans = sum = -1; continue; }
                else vis[id] = 1;
                st.push(id);
                
                if(op == 1) { cnt++; continue; } //不执行 
                
                if(s2[0] == 'n' && s3[0] == 'n') continue;//n n
                if(s2[0] != 'n' && s3[0] == 'n') { ans++; continue; }//1 n
                if(s2[0] == 'n') { op = cnt = 1; continue; } //n 1
                
                bool ok = 0;  //常数 
                if(cnt1 != cnt2) ok = cnt1 > cnt2;
                else 
                {
                    REP(i, 0, cnt1)
                        if(s2[i] != s3[i])
                        {
                            ok = s2[i] > s3[i];
                            break;
                        }
                }
                if(ok) op = cnt = 1; 
            }
        }
        
        if(sum == -1 || !st.empty()) puts("ERR");
        else printf("%s\n", sum == num ? "Yes" : "No");
    }
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sugewud/p/9881099.html