1. 程式人生 > >約瑟夫問題(基於NOIP初賽題的改編)

約瑟夫問題(基於NOIP初賽題的改編)

【問題描述】

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;
}