/*
圓圈中最後剩下的數字:
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 環形鍊錶模擬圓圈 複雜度...