Time Limit Exceeded錯誤的原因
很多時候我們看到Time Limit Exceeded馬上會想到一定是演算法太慢,不符合要求,其實往往還可能遇到一種情況是沒有判斷輸入結束,不然
系統一直在那等你的輸出結果,發現你一直不輸出,或者程式一直不退出,所以給Time Limit Exceeded。
比如讓你輸入整數n,然後輸入n組資料,你應該在n組資料輸完後退出程式。或者如果題目有要求當n不為0時候一直做,那麼加判斷
while(scanf(“%d”,&n)==1 && n!=0 );更有種不明顯的情況是輸入為字串時,你用gets(s1),這時候往往容易忘記了結束程式的條件。
可以這樣判斷while(gets(s1)!=NULL);如果s指向了NULL說明沒有輸入了,應該結束程式。
---------------------
經常會遇到這種令人抓狂的情況
自己編寫的程式在codeblocks上怎麼編譯執行都能輸出正確結果
然而一提交,卻無法Accept,很多時候顯示的並不是Wrong Answer 而是比WrongAnswer更令人絕望的 。
在oj中,給定的Time Limit 是1000MS,出現Time Limit Exceeded則說明這個程式的執行時間超過了這個限度。
經過幾道題,我猜想了幾個關於超時的原因:
————————————————————————————————————————————————————
1.沒有迴圈終止條件。
就是說程式中存在一個迴圈,但是這個迴圈沒有終止條件,或者說是條件太寬泛,在執行的時候雖然能輸出結果,但這個迴圈會一直迴圈下去,導致執行時間過長。
例如:
在1001中,要測試多組資料,進行多次迴圈,
如果這樣寫
for(m=0;m>0;m++)
scanf(.......)
......
企圖讓輸入一直迴圈,理論上並沒有什麼問題,程式也能執行正確,但卻會超時。
因為沒有一個終止的條件,計算機會一直不斷去執行,m只會無限大,這是實際一種很無賴的做法。
而如果要想用一個合理的方式實現無限次迴圈,就需要用
while(scanf()!=EOF)
......
這裡雖然也可無限次的迴圈,卻有了終止條件:返回值為-1 的時候
關於while(scanf()!=EOF)的用法原理,
我再網上查閱得到:
scanf("%d,%d", &a, &b)中
如果a和b都被成功讀入,那麼scanf的返回值就是2
如果只有a被成功讀入,返回值為1
如果a和b都未被成功讀入,返回值為0
如果遇到錯誤或遇到end of file,返回值為EOF。
——————————————————————————————————————————————————————
2.函式呼叫超時。
例如:
在1279中,需要用到一個n的階乘。
在第一次做的時候,我呼叫了一個遞迴函式來求階乘,執行測試正確,卻出現了超時情況。
然後換了一種做法,用一個for迴圈去求階乘,結果就通過了。
我上網查詢得到,遞迴呼叫因為經常會呼叫自身很多次,所以時間的複雜度是指數級別的。
——————————————————————————————————————————————————————
3.程式演算法不夠優化。
就是說自己的程式太複雜,存在更快更有效率的方法。
所以在解決問題時,應儘量選擇簡單的演算法。
如果遇到了這種情況,只能換一個思路了。
——————————————————————————————————————————————————————