题意
给你 两个整数,要求求出约瑟夫问题中最后一个人是谁。
分析
总所周知,约瑟夫问题有模拟 ,线性 。这里解释一种 的解决方法。考虑到我们每次走 个删一个,那么在一圈以内我们可以删掉 个。我们可以模拟这个过程递归求解。由于每次递归问题规模变为 。通过归纳验证时间复杂度大概是
代码
#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); } }