網易QA電面
半小時
1.自我介紹
2.實習經歷
3.對QA職位的認識
4.有10枚硬幣,兩人取,只能取1.2.4,怎樣必贏?
5.有101枚硬幣,其中有一枚重要不同,怎樣判斷出不同的那枚是重是輕?
6.玩什麼遊戲?
7.做過引擎沒?
假如有10枚硬幣,由你和對手兩個人輪流拿,每次只能拿1個、2個或4個;拿走最後一枚硬幣的人,算輸。請問:有沒有必贏的可能?(這好象是騰訊的一道筆試題)解析:因為是拿走最後一枚硬幣的算輸,所以當然應該從最後剩下的硬幣來考慮。其實這個題就是個思路的問題,想到了這個思路,就很簡單。最開始時,我就沒有開啟思路,由剩下的硬幣數,從1到10分10中情況,每一種情況又分那1個、2個、4個三類,判斷輸贏,這樣就剛好繞進去了。正確的思路應該是:因為我們考慮的是必贏的情況,所以我們可以這樣考慮:每次輪到某個人拿時,都能選擇最優的可能,也就是說,只要有贏的可能,就一定會選擇這種情況,即不會錯。所以這裡的一個小原則就是:該我取,我必贏;同理,該對方取,對方也必贏;當一方必贏時,另一方則必輸。那麼,我們不妨假設還剩x枚硬幣,輪到自己取。只要有贏的取法,絕不選擇輸的可能。那麼分情況簡單討論一下:剩餘硬幣(x) (必)輸贏 解釋1 必輸 我必須拿走2 必贏 拿一個3 必贏 拿兩個4 必輸 我無論拿一個還是兩個,都剩3個或兩個,該對方拿,此時他必贏,那我必輸;我拿 4個必輸;所以必輸5 必贏 我拿一個,剩下四個,該對方拿,因為4個必輸,所以此時我必贏6 必贏 同理,我拿2個,我必贏7 必輸 我拿1、2、4個,分別剩6、5、3個,對方必贏,我必輸8 必贏 我拿1個,剩7個9 必贏 我拿2個,剩7個10 必輸 我拿1、2、4,分別剩9、8、6,對方必贏,我必輸從最後的討論結果可知:誰先拿,誰必輸!所以想必贏,讓對手先拿。附:1)分析討論結果可知:在剩餘1、4、7、10個的時候,誰先拿誰必輸.(這個是和同學討論時,他先發現的),所以有可能你某一步取錯了,但只要有可能讓對手取的時候還剩1、4或7個,就還有獲勝的可能,但這就不是必勝的了。2)進一步的規律,就是:硬幣的數量,對3求餘後餘1時,則此時誰先取,誰必輸。3)後來自己用小程式實現了一下這個題目,驗證自己的想法,結果應該是沒有問題的,先附源程式和結果如下,供參考:#include using namespace std;const int COIN_NUM = 30;bool WinLose(int x){ // 四種基本情況的輸贏,也是下面遞迴的基礎 if(x == 1 || x == 4) { return false; } else if( x == 2 || x == 3) { return true; } // 該我取,如果分別取1、2、4個時,對方只要有一種必敗的可能,那我就有必勝的可能;比如,我取了1個之後, // 還剩x個,此時對方無論怎麼取都必敗,那我就必勝;而我的三種取法中,只要任何一種有必勝就可以。 else if((!WinLose(x-1)) || (!WinLose(x-2)) || (!WinLose(x-4))) { return true; } else { return false; }}int main(){ for(int i = 1; i <= COIN_NUM; i ++) { cout << i << " " << WinLose(i) << endl; } return 0;}/* output:1 02 13 14 05 16 17 08 19 110 011 112 113 014 115 116 017 118 119 020 121 122 023 124 125 026 127 128 029 130 1Press any key to continue . . .*/
分成50、50、1三堆:第一次稱兩個50,如果平了,第二次從這100個任意拿1個(當然是真的)與第三堆的1個稱,自然會出結果;第一次稱兩個50不平是正常的,第二次我們把其中的一堆(或重的或輕的都行)分成25、25、稱第二次:1、把輕的分成25、25,如果平了,說明那堆重的有假,當然假的是超重;如果不平,說明這50個輕的有假,假的是輕了;2、把重的分成25、25,道理同上。所以兩次可以發現輕重,但是找不出哪個是假的。