n個人戰成一圈,依次從0~m-1報數,誰是m-1就出圈,下一個人從0重新開始 依次迴圈下去,直到剩一人。
阿新 • • 發佈:2018-11-22
題目描述
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成一個大圈。然後,他隨機指定一個數m,讓編號為0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下一個小朋友開始,繼續0...m-1報數....這樣下去....直到剩下最後一個小朋友,可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。請你試著想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)
/*
問題總結:n個人戰成一圈,依次從0~m-1報數,誰是m-1就出圈,下一個人從0重新開始
依次迴圈下去,直到剩一人。
思路1:利用數學歸納法總結規律
Xn表示有n個小朋友時,留在最後的小朋友的角標,m不變
則有以下規律:Xn = (Xn-1 + m) % n;//關鍵,此類問題的通解。
由以上公式,顯然利用遞迴就能求解。
*/
class Solution { public: int LastRemaining_Solution(int n, int m) { if(n == 0) return -1; if(n == 1) return 0; else return(LastRemaining_Solution(n-1,m) + m) % n; } };
/*
思路2:用陣列來模擬環
*/
class Solution { public: int LastRemaining_Solution(int n, int m) { if(n<1 || m<1) return -1; vector<int> temp(n,0); int i = -1,step = 0,count = n,index = -1; while(count>0){ i++; index = i % n; if(temp[index] == -1) continue; step++; if(step == m){ temp[index] = -1; step = 0; count--; } } return index; } };