前言
首先,hduoj已經出現多年,上面的大部分經典題目已經被被人咀嚼透爛了,也能通過搜尋引擎搜尋到許多現成的**。如果有測試資料,那麼就能拿自己的程式的輸出與前人的程式的輸出進行比對,找出問題所在。
然後,對於沒有被別人嚼爛的題目,也可以借助測試資料,更好地分析程式問題所在,不至於僅僅過了簡單的sample而過不了測試資料。
最後,對於想刷單題排行榜的人,可以嘗試衝擊0ms、0kb的極限。
一直很疑惑,哪些0ms,0kb的評判結果是怎麼出來的。
測試資料的獲取方法
在faq頁面,可以看到候選答案提交之後online judge的多種反饋結果。
只需選擇其中3種我們有把握一定能產生的錯誤,那麼就可以通過二分法,將測試資料的長度以及測試資料的每個位元組都找出來。
獲取測試資料的長度
設定猜測長度guess,結合讀取到的實際長度,比較兩者,分別人為地產生3種錯誤即可折半地逼近正確的實際長度。
其**如下
#include #define maxlen 0x7fffffff
#define minlen 0
char buffer[0x10000];//64kb
int guess = 0;
// re
void equal(void)
// ole
void less(void)
}// tle
void greater(void)
}int main(void)
if (count < guess)
else if (count == guess)
else
return 0;
}
顯然,最多隻需猜測log2(maxlen)次即可,就算他是32位整數,也就是31次猜測,必然得出測試資料的長度來。
獲取測試資料的每個位元組
同樣是利用二分法來猜測每個位元組的值。每個位元組只需最多8次猜測即可得出結果。其**如下:
#include int guess = 0;
int skip = 0;
// re
void equal(void)
// ole
void less(void)
}// tle
void greater(void)
}int main(void)
if (count == skip)
else if (ch < guess)
else
}count++;
} return 0;
}
優化
對於某些題目,如果我們預先知道了輸入資料僅僅是ascii文字,那麼很顯然可以將猜測範圍縮小至0~127的範圍。
對於另一些題目,比如輸入是整數,整數之間以空白符(空格、回車、tab)分割,那麼顯然猜測範圍可以進一步縮小為'0'~'9'以及'\n','\t', ' ',一共13種。如此一來最多隻需猜測4次即可得出每個位元組的值。
杭電oj 2102 A計畫
problem description 可憐的公主在一次次被魔王擄走一次次被騎士們救回來之後,而今,不幸的她再一次面臨生命的考驗。魔王已經發出訊息說將在t時刻吃掉公主,因為他聽信謠言說吃公主的肉也能長生不老。年邁的國王正是心急如焚,告招天下勇士來拯救公主。不過公主早已習以為常,她深信智勇的騎士lj肯...
杭電OJ 2016 資料的交換輸出
problem description 輸入n n 100 個數,找出其中最小的數,將它與最前面的數交換後輸出這些數。input 輸入資料有多組,每組佔一行,每行的開始是乙個整數n,表示這個測試例項的數值的個數,跟著就是n個整數。n 0表示輸入的結束,不做處理。output 對於每組輸入資料,輸出交...
杭電OJ 2016 資料的交換輸出
problem description 輸入n n 100 個數,找出其中最小的數,將它與最前面的數交換後輸出這些數。input 輸入資料有多組,每組佔一行,每行的開始是乙個整數n,表示這個測試例項的數值的個數,跟著就是n個整數。n 0表示輸入的結束,不做處理。output 對於每組輸入資料,輸出交...