約瑟夫問題(基於NOIP初賽題的改編)
阿新 • • 發佈:2018-12-15
【問題描述】
YJC 很喜歡玩遊戲,今天他決定和朋友們玩約瑟夫遊戲。
約瑟夫遊戲的規則是這樣的:n 個人圍成一圈,從1 號開始依次報數,當報到m 時,
報1、2、...、m-1 的人出局,下一個人接著從1 開始報,保證(n-1)是(m-1)的倍數。最後剩的一個人獲勝。
YJC 很想贏得遊戲,但他太笨了,他想讓你幫他算出自己應該站在哪個位置上。
據說有O(1)的打表結論,然而我並不瞭解。。。
我會遞推!
想象每次都是把人數n/m個人,就是每個第m的倍數上的人進入下一輪,剩餘人數輪下去,作為開頭。
這樣相當於要求的數在第這一輪裡是m的倍數,如果這一輪不是從1開始(就是上一輪有輪下來的),就是m的倍數減去餘數
這樣遞迴到最後就剩一個返回1即可。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; ll n,m; ll gett(ll x,ll yu) { if(x==1)return 1; return m*gett(x/m+x%m,x%m)-yu; } int main() { scanf("%I64d%I64d",&n,&m); ll ans=m*gett(n/m+n%m,n%m); printf("%I64d",ans); return 0; }