1. 程式人生 > >P3952 時間復雜度

P3952 時間復雜度

lib 大寫 top ostream 框架 自己 cout 一個 base

P3952 時間復雜度

題目描述

小明正在學習一種新的編程語言 A++,剛學會循環語句的他激動地寫了好多程序並 給出了他自己算出的時間復雜度,可他的編程老師實在不想一個一個檢查小明的程序, 於是你的機會來啦!下面請你編寫程序來判斷小明對他的每個程序給出的時間復雜度是否正確。

A++語言的循環結構如下:

F i x y
    循環體
E

其中F i x y表示新建變量 iii (變量 iii 不可與未被銷毀的變量重名)並初始化為 xxx , 然後判斷 iii 和 yyy 的大小關系,若 iii 小於等於 yyy 則進入循環,否則不進入。每次循環結束後 iii 都會被修改成 i+1i +1i+1 ,一旦 iii 大於 yyy 終止循環。

xxx 和 yyy 可以是正整數( xxx 和 yyy 的大小關系不定)或變量 nnn 。 nnn 是一個表示數據規模的變量,在時間復雜度計算中需保留該變量而不能將其視為常數,該數遠大於 100100100 。

“E”表示循環體結束。循環體結束時,這個循環體新建的變量也被銷毀。

註:本題中為了書寫方便,在描述復雜度時,使用大寫英文字母“O”表示通常意義下“Θ”的概念。

輸入輸出格式

輸入格式:

輸入文件第一行一個正整數 ttt ,表示有 ttt ( t≤10t \le 10t10 )個程序需要計算時間復雜度。 每個程序我們只需抽取其中 F i x y

E即可計算時間復雜度。註意:循環結構 允許嵌套。

接下來每個程序的第一行包含一個正整數 LLL 和一個字符串, LLL 代表程序行數,字符 串表示這個程序的復雜度,O(1)表示常數復雜度,O(n^w)表示復雜度為 nwn^wnw ,其 中w是一個小於100的正整數(輸入中不包含引號),輸入保證復雜度只有O(1)O(n^w) 兩種類型。

接下來 LLL 行代表程序中循環結構中的F i x y或者 E。 程序行若以F開頭,表示進入一個循環,之後有空格分離的三個字符(串)i x y, 其中 iii 是一個小寫字母(保證不為 nnn ),表示新建的變量名, xxx 和 yyy 可能是正整數或 nnn ,已知若為正整數則一定小於 100。

程序行若以E開頭,則表示循環體結束。

輸出格式:

輸出文件共 ttt 行,對應輸入的 ttt 個程序,每行輸出YesNo或者ERR(輸出中不包含引號),若程序實際復雜度與輸入給出的復雜度一致則輸出Yes,不一致則輸出No,若程序有語法錯誤(其中語法錯誤只有: ① F 和 E 不匹配 ②新建的變量與已經存在但未被銷毀的變量重復兩種情況),則輸出ERR

註意:即使在程序不會執行的循環體中出現了語法錯誤也會編譯錯誤,要輸出 ERR

輸入輸出樣例

輸入樣例#1:
8
2 O(1)
F i 1 1
E
2 O(n^1)
F x 1 n
E
1 O(1)
F x 1 n
4 O(n^2)
F x 5 n
F y 10 n
E
E
4 O(n^2)
F x 9 n
E
F y 2 n
E
4 O(n^1)
F x 9 n
F y n 4
E
E
4 O(1)
F y n 4
F x 9 n
E
E
4 O(n^2)
F x 1 n
F x 1 10
E
E
輸出樣例#1:
Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

說明

【輸入輸出樣例解釋1】

第一個程序 iii 從 1 到 1 是常數復雜度。

第二個程序 xxx 從 1 到 nnn 是 nnn 的一次方的復雜度。

第三個程序有一個 F 開啟循環卻沒有 E 結束,語法錯誤。

第四個程序二重循環, nnn 的平方的復雜度。

第五個程序兩個一重循環, nnn 的一次方的復雜度。

第六個程序第一重循環正常,但第二重循環開始即終止(因為 nnn 遠大於100,100大於4)。

第七個程序第一重循環無法進入,故為常數復雜度。

第八個程序第二重循環中的變量 xxx 與第一重循環中的變量重復,出現語法錯誤②,輸出 ERR

【數據規模與約定】

對於 30%30\%30% 的數據:不存在語法錯誤,數據保證小明給出的每個程序的前 L/2L/2L/2 行一定為以 F 開頭的語句,第 L/2+1L/2+1L/2+1 行至第 LLL 行一定為以 EEE 開頭的語句, L≤10L \le 10L10 ,若 xxx 、 yyy 均 為整數, xxx 一定小於 yyy ,且只有 yyy 有可能為 nnn 。

對於 50%50\%50% 的數據:不存在語法錯誤, L≤100L \le 100L100 ,且若 xxx 、 yyy 均為整數, xxx 一定小於 yyy , 且只有 yyy 有可能為 nnn 。

對於 70%70\%70% 的數據:不存在語法錯誤, L≤100L \le 100L100 。

對於 100%100\%100% 的數據: L≤100L \le 100L100 。


如果需要Hack請私信@zhouyonglong或發討論,提供數據和能Hack掉的P3952或本題的AC記錄。

————————————————————————————————————————————————————————————

emmmm……先考慮程序框架真的很重要啊

然而得了73。發現把comp打成bool了

然而改了之後得了91……又看了10分鐘發現vis數組開小了

2個小時……終於A了

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int INF = 1000000;

int comp(string &str) {
    if (str[0] >= 0 && str[0] <= 9)
        return atoi(str.c_str());
    else return INF;
}

int main() {
    int t;
    cin >> t;
    while (t --) {
        bool ERR_FLAG = false, imPossible = false, vis[1010];
        bool EnteryPossible[1010];
        int L; string str_s, ch_first;
        int stack[1010], top = 0;
        int NowFZD[1010], QW_FZD = 0, SJ_FZD = 0, MAX_SJFZD = 0;
        
        memset(vis, false, sizeof(vis));
        memset(EnteryPossible, false, sizeof(EnteryPossible));
        memset(NowFZD, 0, sizeof(NowFZD));
        
        cin >> L; cin >> str_s;
        if (str_s[2] == 1) QW_FZD = 0;
        else sscanf(str_s.c_str(), "O(n^%d)", &QW_FZD);
        
        while (L --) {
            cin >> ch_first;
            
            if (ch_first == "F") {
                string i, x, y;
                cin >> i >> x >> y;
                
                if (ERR_FLAG) continue;
                if (vis[(int)i[0]]) { 
                    ERR_FLAG = true;
                    continue;
                }
                
                stack[++top] = (int)i[0]; 
                NowFZD[(int)i[0]] = SJ_FZD;
                EnteryPossible[(int)i[0]] = imPossible;

                if (imPossible);
                else if (comp(x) > comp(y)) imPossible = true;
                else if (x != "n" && y == "n") {
                    SJ_FZD++;
                    MAX_SJFZD = max(MAX_SJFZD, SJ_FZD);
                }
                
                vis[(int)i[0]] = true;
            }

            else if (ch_first == "E") {
                if (ERR_FLAG) continue;
                if (top <= 0) {
                    ERR_FLAG = true;
                    continue;
                }
                
                vis[stack[top]] = false;
                SJ_FZD = NowFZD[stack[top]];
                imPossible = EnteryPossible[stack[top]];
                -- top;
            }
        }
        
        if (ERR_FLAG || top != 0) cout << "ERR" << endl;
        else if (MAX_SJFZD == QW_FZD) cout << "Yes" << endl;
        else cout << "No" << endl; 
    }
    return 0;
}

P3952 時間復雜度