洛谷p3952
這一道模擬題是真的特別考細心的一道題……調了半天才調出來……要是今年noip考到這樣的模擬題我可能就涼涼
設變數ci[i]表示第i層的時間複雜度是o(n^ci[i])
對於每次進入乙個迴圈('f'),我們考慮這麼幾種情況:
1、此層迴圈不會執行(外層迴圈x>y)
只需判斷此層迴圈是否有語法錯誤(變數重複)即可
2、此層迴圈會執行,需要判斷此層迴圈是否有語法錯誤(變數重複)並計算時間複雜度
讀入後先判斷是否有語法錯誤(變數重複),並記錄此變數
①可以進入此層迴圈(x<=y)
若x為正整數,y為n,此層迴圈的時間複雜度=上一層時間複雜度+1;否則此層迴圈時間複雜度=上一層時間複雜度
②不能進入此層迴圈(x>y)
做標記,並記錄位置(便於刪除標記)
對於每次退出乙個迴圈('e'):
1、刪除變數
2、若此迴圈x>y(此前做的標記),則刪除標記
幾個實現細節:
q:如何記錄變數並判斷變數是否重複?
a:用tot和alpha記錄迴圈層數及其變數名稱,再用利用雜湊的思想用陣列hash[i]表示字母i在外層迴圈是否出現過,雜湊函式也很簡單,直接用ascii碼做雜湊函式,訪問是直接hash['字母']即可
q:如何判斷x,y的大小?
a:不能用string過載的運算子!string過載的運算子比較方法是從前向後逐個比較……和我們的需求不一樣。可以寫乙個dayu()函式(博主英語不好),注意x,y為n的情況,然後判斷x,y的長度,最後再逐個比較。還有一些比較巧妙的實現細節讀者在**裡感受一下。
1 #include2 #include3 #include4 #include5
using
namespace
std;
6bool hash[128];//
判斷字元是否使用過
7char alpha[101];//
儲存使用過的字母
8int ci[101];//
每一層的時間複雜度
9bool pd(int ans,string fuzadu)//
判斷時間複雜度為n^w是是否正確
1019
return
pd;20}21
bool dayu(string x,string y)//
上面已經判斷過x為數字,y為n的情況,故此處不用判斷
2236
return0;
37}38int
main()
3967
if(!not_do)//
此層迴圈執行,計算時間複雜度
6874
else
if(dayu(x,y))//
x>y,此層迴圈不執行,做標記,時間複雜度不變
7579
else
//否則時間複雜度不變
80 ci[ceng]=ci[ceng-1
];81}82
}83else
//退出迴圈
8489}90
if(wrong||ceng)//
有語法錯誤
91 cout<<"
err"
<92else
if(ans&&pd(ans,fuzadu))//
時間複雜度為o(n^ans)
93 cout<<"
yes"
<94else
if(!ans&&fuzadu[2]=='
1')//
時間複雜度為o(1)
95 cout<<"
yes"
<96else
97 cout<<"no"
<99return0;
100 }
**寫的比較亂神犇們不喜勿噴哈
幾個注意事項:
1、每組資料一定要清空各種變數&陣列!
2、判斷時間複雜度是否為o(n^w)要注意w不一定是一位數……我第一次就因為這個wa掉了好幾個點
3、寫dayu()函式的時候要嚴謹一些……情況比較多,最好先用大量資料測試一下(血的教訓啊)
NOIP2017 D1T2 時間複雜度
時間複雜度 題目背景 noip2017 d1t2 分析 模擬 棧 講真因為 t1有點影響心情,考場上打這個題的時候有點混亂,不過好歹最後 a了,雖然 各種不能看,其實就相當於乙個人工棧,乙個 f表示加入,e表示彈出,這樣最後可以比較方便的判定非法,然後中途就是判定有多少個 n,和多少個常數複雜度。然...
NOIP2017 D1T2時間複雜度
這道題在考試時看到感覺與第一題放反了位置 因為我還沒有看到第一題是結論題 對於每個語句進行棧的模擬,而如果有語法錯誤就特判。對於每一條for語句我們將其與棧頂元素連邊,複雜度是1的我們不用考慮,如果複雜度是n我們就算他的貢獻加一。這樣我們求最大複雜度就相當於求一顆子樹的最大深度,當然如果這條語句不合...
NOIP 2017 Day1 T2 時間複雜度
luogu題面 大模擬.並不難 然而考場上寫掛了 用3 個讀入函式,解決讀入問題 雙棧齊發,乙個記錄使用過的字母,另乙個記錄複雜度貢獻情況 用bre表示當前跳出迴圈的層數 用err表示當前編譯狀態 是否編譯失敗 s和ans分別表示當前複雜度和總複雜度 那麼當讀取到 f 時,我們就要做以下幾點 讀取迴...