題目描述
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。hf作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成乙個大圈。然後,他隨機指定乙個數m,讓編號為0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下乙個小朋友開始,繼續0…m-1報數…這樣下去…直到剩下最後乙個小朋友,可以不用表演,並且拿到牛客名貴的「名偵探柯南」典藏版(名額有限哦!!_)。請你試著想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)
其實就是約瑟夫環問題
解一:
思路是:模擬報數過程,用陣列或者鍊錶記錄數,每次刪除乙個數,直至剩乙個數。
時間複雜度:o(nm)
下面是鄙人不成熟的**。請多擔待。
public
intlastremaining_solution
(int n,
int m)
boolean
kids =
newboolean
[n];
int count = n;
// 剩餘孩子數目
int cur =0;
// 報數順序
int idx =0;
// 當前孩子位置
while
(count >1)
idx =
(idx +1)
% n;
// 取餘,用於迴圈}if
(idx ==0)
else
count--;}
for(
int i =
0; i < kids.length; i++
)return-1
;}
解二:把n個人的編號改為0~n-1,然後對刪除的過程進行分析。
第乙個刪除的數字是(m-1)%n,幾位k,則剩餘的編號為(0,1,…,k-1,k+1,…,n-1),下次開始刪除時,順序為(k+1,…,n-1,0,1,…k-1)。
用f(n,m)表示從(0~n-1)開始刪除後的最終結果。
用q(n-1,m)表示從(k+1,…,n-1,0,1,…k-1)開始刪除後的最終結果。
則f(n,m)=q(n-1,m)。
下面把(k+1,…,n-1,0,1,…k-1)轉換為(0~n-2)的形式,即
k+1對應0
k+2對於1
…k-1對應n-2
轉化函式設為p(x)=(x-k-1)%n, p(x)的逆函式為p^(x)=(x+k+1)%n。
則f(n,m)=q(n-1,m)=p^(f(n-1,m))=(f(n-1,m)+k+1)%n,又因為k=(m-1)%n。
f(n,m)=(f(n-1,m)+m)%n;
最終的遞推關係式為
f(1,m) = 0; (n=1)
f(n,m)=(f(n-1,m)+m)%n; (n>1)
附上我的解釋:
f(n,m)=q(n-1,m),
又根據轉化關係有,轉化函式設為p(x)=(x-k-1)%n。
我想不明白。我腦子好像銹住了。
public
intgetresult
(int n,
int m)
int last =0;
for(
int i=
2;i<=n;
++i)
// 因為實際編號為(1~n)
return
(last+1)
;}
劍指offer 孩子們的遊戲
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。hf作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的 首先,讓小朋友們圍成乙個大圈。然後,他隨機指定乙個數m,讓編號為0的小朋友開始報數。每次喊到m 1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮...
劍指 offer 孩子們的遊戲
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。hf作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的 首先,讓小朋友們圍成乙個大圈。然後,他隨機指定乙個數m,讓編號為0的小朋友開始報數。每次喊到m 1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮...
劍指offer 孩子們的遊戲
每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。hf作為牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的 首先,讓小朋友們圍成乙個大圈。然後,他隨機指定乙個數m,讓編號為0的小朋友開始報數。每次喊到m 1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮...