該如何去想這個問題呢? 第一眼的想法是建立一個決策樹, 根節點是某數字, 每個 分支代表電腦回答此數字的可能答案, 每一個子樹則要決定在該位置要猜哪個數字好. 不過若你這樣去思考, 會發覺此決策樹非常大而複雜, 要找張夠大的紙, 花個幾天的 時間在上面推演, 然後再寫個幾千行的程式來完成.
另一種思考方式, 則是消去法. 若大家還記得歸納法的話, 若要證明某定理對所有的 N>=1都成立, (1)先證明N=1成立, (2)若N成立可推得N+1也成立, 由(1)(2)該定理成立. 這方法的 原理是, 只要問題是可數的(如自然數), 我們可從1一路數下去, 總有一天會數到N. 消去法也是差不多的意思, 只要該問題的可能解是有限個, 那我們只要每次 (想到迴圈了嗎?)都至少消去一組不可能的解, 那麼總有一天會消去所有不可能的解, 留下的自然就是正確的解答了. 在猜四位數字的問題裡, 可能的解有10*9*8*7種, 剩下的問題就是如何消去不可能的解了. 我們猜G, 電腦回答nm, 則電腦手中的數字X 有甚麼性質? G # X = nm !!! 也就是說目前還沒有被消去的任意可能解答Y, 必定要 符合 G # Y = nm, 否則 Y 就不可能是 X. 當然有個小地方要注意的是, 若nm = 40, 則G就是X, 否則G一定不是X.
此作業解答的範例如下byte[] studentID = {8,7,3,2,1,0,0,6}; Socket s = new Socket("163.22.20.114",1234); InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); byte ans = new byte[2]; try { out.write(studentID); for (int i=0; i<100; i++) { while (true) { byte[] guess = guess(); // your guess method out.write(guess); in.read(ans); if (ans[0]==4 && ans[1]==0) { break; } eliminate(guess, ans); // 消去所有不可能的解答 } } in.close(); out.close(); s.close(); } catch(Exception ex) { System.out.println(ex); }