劍指Offer 面試題45 圓圈中最後剩下的數字

2021-06-25 13:53:39 字數 1406 閱讀 9296

/*

圓圈中最後剩下的數字:

0,1,。。。,n-1這n個數字排成乙個圓圈,從數字0開始每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡

剩下的最後乙個數字。

這是c語言書上的一道題目

設定乙個剪枝陣列,設定乙個迴圈,迴圈出口是只剩乙個元素,剛開始置剩餘元素總數目為n,後面會更新。

注意每次當計數器變數走到n時,表明乙個迴圈結束了,應將n變為0,從頭開始遍歷,小的圓圈是通過m取餘來遍歷

更新,每當步數計數器的步數達到m步,置當前元素未刪除,重置步數為0,

輸入:輸入有多組資料。

每組資料一行,包含2個整數n(0<=n<=1,000,000),m(1<=m<=1,000,000),n,m分別表示小朋友的人數(編號1....n-1,n)和hf指定的那個數m(如上文所述)。如果n=0,則結束輸入。

輸出:對應每組資料,輸出最後拿到大獎的小朋友編號。

樣例輸入:

1 10

8 56 6

6 30

樣例輸出:13

41*//*

關鍵:1先對未訪問過的人,才能累加報數

if(!_imarkarr[icnt])//如果沒有訪問這個人,才累加報數

2一旦累加報數後,立即判斷是否達到臨界值,並清空報數為0,而不是1

if(istep == m)//判斷報數

icnt++;

if(icnt > n)//如果已經到達最後乙個人,再從頭開始迴圈。注意:從頭到尾的計數需要放在後面,不能影響剪枝

3利用公式f(n,m) =

return last + 1;//注意人頭編號是從1開始的,因此針對適用於編號為0的結果基礎上再加1

*/#include #include const int maxsize = 1e6 + 1;

int _imarkarr[maxsize];

int lastnumber(int n,int m)

if(istep == m)//判斷報數

icnt++;

if(icnt > n)//如果已經到達最後乙個人,再從頭開始迴圈。注意:從頭到尾的計數需要放在後面,不能影響剪枝

}for(int i = 1 ; i <= n ; i++) }

}int lastnumber2(int n,int m)

return last + 1;//注意人頭編號是從1開始的,因此針對適用於編號為0的結果基礎上再加1

}void process()

scanf("%d",&m);

memset(_imarkarr,0,sizeof(_imarkarr));

printf("%d\n",lastnumber2(n,m)); }}

int main(int argc,char* argv)

劍指Offer 面試題45 圓圈中最後剩下的數字

題目 0,1,n 1這n個數字排成乙個圓圈,從數字0開始每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。思路 下面,我們主要介紹,用動態規劃來解決問題的方式。1 首先,我們定義乙個關於n m的方程 f n,m 該方程表示在n個數字中每次刪除第m個數字最後剩下的數字 根據1中的定義,...

劍指offer 面試題62 圓圈中最後剩下的數字

面試題 劍指offer 題目解答 0,1,n 1這n個數字排成乙個圈,從數字0開始,每次從這個圓圈裡刪除第m個數字,求這個圓圈裡剩下的最後乙個數字。書中給出了乙個經典的環形鍊錶的解題方法,但是在n數字較大的時候,你會發現,再環中的很多數字都會被多次重複遍歷,並且需要乙個輔助鍊錶來進行操作。所以,使用...

劍指offer 面試題62 圓圈中最後剩下的數字

問題 0,1,n 1這n個數字排成乙個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。例如,0 1 2 3 4這5個數字組成乙個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2 0 4 1,因此最後剩下的數字是3。思路1 環形鍊錶模擬圓圈 複雜度...