题解 P1826 【猴子选大王数据再加强版】
约瑟夫问题典型例题
这类问题模板:
n 个人标号 1~ n。逆时针站一圈,从1号开始,每一次从当前的人逆时针数m个,然后让这个人出局。问最后剩下的人是谁。
我们思考,有
我们设
那么可以得到递推式子:
这样是编号从0开始的,我们想要编号从1开始
那么:
最后别忘了要从
代码:
#include <bits/stdc++.h>
using namespace std;
int f[1000010];
int vis[1000010];
int a,b,m;
int main()
{
scanf("%d%d%d",&a,&b,&m);
f[1] = 1;
int ans = 0;
for(int i = 1;i <= b;i++)
{
f[i] = (f[i-1]+m-1)%i+1;
if(i>=a)
{
vis[f[i]]++;
ans = max(ans,vis[f[i]]);
}
}
printf("%d\n",ans);
for(int i = 1;i <= b;i++)
{
if(vis[i] == ans) printf("%d ",i);
}
return 0;
}