A - 约瑟夫环
作者:互联网
A - 约瑟夫环
N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2。2号先出列,然后是1号,最后剩下的是3号。
Input
2个数N和K,表示N个人,数到K出列。(2 <= N, K <= 10^6)
Output
最后剩下的人的编号
Sample Input
3 2Sample Output
3Sponsor
普通的约瑟夫环写法TLE(最大1E12,我冒险试了试,爆0...)
看了书,这个用递归解决,每次递归形成一个新的环,用新编号计算旧编号,再对编号进行处理
旧编号=(新编号+报数值k)%总人数n,我是这么理解的:上一轮报到t出局,这一轮从t+1开始,经过了k个人,下一轮重新编号的时候较上次落后了k个人,加上,再对上一轮的总人数取模,就得到了上一轮相应的编号
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
using namespace std;
int all, k;
int YSFloop(int n, int m, int target);
//分别表示总人数,数到第几出局,第几出局的人,
//这题要求只剩一个人,所以最后一个参数不要也罢
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> all >> k;
cout << YSFloop(all, k, all) + 1;
//由于取模会出现比递推值少1的情况(比如10%10=0,而他本应回到环首,编号为1),所以+1
return 0;
}
int YSFloop(int n, int m, int target) {
if (target == 1) {
return (m + n) % n;//当最后一个人被淘汰时,用这一轮的编号求它的初始编号
}
return (YSFloop(n - 1, m, target - 1) + m) % n;
}
还有一个大佬用循环写的,真是小母牛烤火...这是他的码:
#include <cstdio>
using namespace std;
#define maxn 1000006
int f[maxn];
int n,k;
int main()
{
scanf("%d%d",&n,&k);
for (int i=2;i<=n;i++)
f[i]=(f[i-1]+k) % i;
printf("%d",f[n]+1);
return 0;
}
标签:数到,出列,int,一轮,约瑟夫,编号,include 来源: https://blog.csdn.net/bairimeng16/article/details/122663781