题意
给你 两个整数,要求求出约瑟夫问题中最后一个人是谁。
分析
总所周知,约瑟夫问题有模拟 ,线性
。这里解释一种
的解决方法。考虑到我们每次走
个删一个,那么在一圈以内我们可以删掉
个。我们可以模拟这个过程递归求解。由于每次递归问题规模变为
。通过归纳验证时间复杂度大概是
代码
#include<bits/stdc++.h>
using namespace std;
int read(){
int x=0,f=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f?-x:x;
}
int solve(int n,int k) {
if(n==1)return 0;
if(k==1)return n-1;
if(k>n)return (solve(n-1,k)+k)%n;
int res=solve(n-n/k,k);
res -= n%k;
if(res<0)res+=n;
else res+=res/(k-1);
return res;
}
int main() {
while(1) {
int n=read(),k=read();
if(!n&&!k) return 0;
printf("%d\n",solve(n,k)+1);
}
}
京公网安备 11010502036488号