1. 程式人生 > >[NOIp 2017] Complexity

[NOIp 2017] Complexity

string corona pac 我不 查詢 () 一次 [] 初始

洛谷 3952

輸入一整行字符串時,如果中間有空格,則不能用 scanf("%s",...) 來輸入!
scanf() 會在空格處停下!

在NOIp2018 前夕終於做出了NOIp2017的題

Candy? 說這道題用棧做,其實完全可以不用棧我不會,於是用一個比較笨拙的方法:找出與每個F配對的E,然後從第一個循環開始處理。

利用循環結構處理並列的FE,遞歸處理嵌套的FE

用一個集合記錄變量的名字,當遇到一個新變量名字時,查詢是否沖突,一個循環結束改後,及時刪除這個變量名。

第一次提交時只有 37 分,輸出中間結果發現 match 過程中出現問題。。。冥思苦想好久不得其解,往上一翻翻然醒悟:

match 數組應該開 MAXL=100+10 的大小,結果寫成了int match[MAXN]

,只開了 20 。。。

寫程序時一定要細心!!!不能再犯這種低級錯誤!!!

//Copyright(C)Corona.
//2018-10-29
#include <set>
#include <stack>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int MAXL=100+10,MAXN=20;
char p[MAXL][MAXN];
int match[MAXL];
set<string> var;

inline void scanf(char cache[],char End,int maxn) {
    for(int i=0; i<maxn; i++) {
        char c=getchar();
        if(c==End || c==‘\0‘) {
            cache[i]=‘\0‘;
            return;
        } else {
            cache[i]=c;
        }
    }
    cache[maxn]=‘\0‘;
}

inline void scanf(int& x,char str[]) {
    x=0;int len=strlen(str),f=0;
    for(int i=0;i<len;i++) {
        if(str[i]<‘0‘ || str[i]>‘9‘) {
            if(str[i]==‘^‘) f=1;
        } else {
            x=x*10+str[i]-‘0‘;
        }
    } x*=f;
}

inline void Match(int L,int& err) {
    memset(match,-1,sizeof(match));
    for(int i=0; i<L; i++)
        if(p[i][0]==‘F‘) {
            int cf=1;
            for(int j=i+1; j<L; j++) {
                cf += (p[j][0]==‘F‘?1:-1);
                if(!cf) {
                    match[i]=j;
                    break;
                }
            }
        }
}

inline void getName(char pro[],string& name,string& from,string& to) {
    int l=strlen(pro),cnt=0;
    char a[3][MAXN];
    for(int i=0; i<l; i++) {
        if(pro[i]==‘ ‘) {
            cnt++;
            for(int j=i+1,k=0; j<=l; j++,k++) {
                a[cnt-1][k]=pro[j];
                if(pro[j]==‘ ‘ || pro[j]==‘\0‘ || j==l) {
                    a[cnt-1][k]=‘\0‘;
                    break;
                }
            }
        }
    }
    name=a[0];from=a[1];to=a[2];
}
inline int num(string& s) {
    int n=0;
    for(int i=0,m=s.length(); i<m; i++) {
        n=n*10+s[i]-‘0‘;
    }
    return n;
}
inline int solve(int start,int end,int& err) {
    int init,in_loop=1;
    string name,from,to;
    if(start == -1) {
        //初始化為O(1)
        init=0;
    } else {
        //初始化為當前 F 循環的復雜度
        getName(p[start],name,from,to);
        if(var.count(name)) {
            err=5;
        } else {
            var.insert(name);
        }

        if(from=="n" && to=="n") {
            init=0;
        } else if(from=="n" && to!="n") {
            init=0;
            in_loop=0;//未進入循環
        } else if(from!="n" && to=="n") {
            init=1;
        } else {
            init=0;
            if(num(from)>num(to)) in_loop=0;
        }
    }

    int inc=0;//初始化為O(1)
    for(int i=start+1; i!=end; i++) {
        if(p[i][0]==‘F‘) {
            inc=max(inc,solve(i,match[i],err));
            i=match[i];
        }
    }
    var.erase(name);
    return in_loop==1?init+inc:0;
}

int main() {
    int T;
    cin>>T;
    while(T--) {
        int L;
        cin>>L;
        char his_ans[MAXN];
        scanf(his_ans,‘\n‘,MAXN);
        int complexity,com=0;
        scanf(complexity,his_ans);
        int err=0,cnt=0;
        for(int i=0; i<L; i++) {
            scanf(p[i],‘\n‘,MAXN);
            if(p[i][0]==‘F‘) cnt++;
            else if(p[i][0]==‘E‘) cnt--;
            if(cnt<0) {
                err=1;
            }
        }
        if(cnt!=0) err=2;
        else {
            Match(L,err);
            com=solve(-1,L,err);
        }
        if(err) {
            printf("ERR\n");
        } else {
            if(com==complexity) {
                printf("Yes\n");
            } else {
                printf("No\n");
            }

        }
    }
    return 0;
}

[NOIp 2017] Complexity