題目描述
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。hf作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成乙個大圈。然後,他隨機指定乙個數m,讓編號為0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下乙個小朋友開始,繼續0…m-1報數….這樣下去….直到剩下最後乙個小朋友,可以不用表演,並且拿到牛客名貴的「名偵探柯南」典藏版(名額有限哦!!^_^)。請你試著想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)經典解法:
我們使用乙個陣列來模擬這些孩子,當孩子還沒有被挑選到,就設為0,如果孩子被挑出,就設為1,如果已經遍歷到了結尾,就移到陣列的開頭,直到最後剩下乙個孩子。創新解法:
在這n個數字中,第乙個被刪除的數字是(m - 1)% n,為了簡單起見,我們將其記作k,刪除k之後剩下的n-1個數字為0, 1, 2, 3, … , k -1, k + 1, … , n - 1, 並且下一次刪除從k +1開始計數,但顯然該數列最後剩下的數字也是應該關於n和m的函式,我們將其記作f』(n - 1, m),最初序列剩下的最後乙個數字一定是刪除乙個數字之後的序列的最後剩下的數字,即f(n, m)= f』(n - 1, m)。**如下:剩下的乙個陣列序列可以產生這樣的對映:
k + 1 -> 0
k + 2 -> 1
… n - 1 -> n - k - 2
0 -> n - k - 1
1 -> n - k
… k - 1 -> n - 2
對映定義為p,則p(x) = (x - k - 1) % n,逆對映p^(-1)(x)= (x + k + 1)%n, 對映之後的序列和之前的序列有同樣的形式,所以可以記作f(n - 1, m ),根據我們的對映,對映之前的序列中最後剩下的數字f』(n - 1, m) = p ^(-1)[f(n - 1, m)] = [f(n - 1, m) + k + 1] % n = [f(n - 1, m ) + m] % n = f(n, m).
public
static
intlastremaining_solution(int n, int m)
int count = n;
int result = new
int[n];
int temp = 0;
int i = 0;
while (count > 1)
if (result[i] == 0)
if (temp == m)
i++;
}int j;
for (j = 0; j < n; j++)
}return j;
}public
static
intlastremaining_solution2(int n, int m)
int last = 0;
for (int i = 2; i <= n; i++)
return last;
}
圓圈中最後剩下的數字
1.問題描述 題目0,1.n 1這n個數字排成乙個圓圈,從數字0開始每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。來自 劍指offer 2.分析 1 用環形鍊錶模擬圓圈,然後掃瞄鍊錶刪除結點,如果掃瞄到了鍊錶結尾,重新在指向鍊錶開頭以此來模擬環形鍊錶。typedef struct...
圓圈中最後剩下的數字
題目 0,1,n 1這n個數字排成乙個圓圈,從數字0開始每次從這個圓圈裡刪除第m個數字。求這個圓圈裡剩下的最後乙個數字。分析 1.利用環形鍊錶模擬圓圈求解。2.利用刪除之後的規律求解。環形鍊錶 class solution circleiter circlelist.begin while circ...
圓圈中最後剩下的數字
題目要求 0,1,2.n 1這n個數字拍成乙個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字,求剩下的最後乙個數字。例如0,1,2,3,4這5個數字組成的圈,每次刪除第3個數字,一次刪除2,0,4,1,因此最後剩下的是3。解題思路 最直接的思路是用環形鍊錶模擬圓圈,通過模擬刪除過程,可以得到最後...