其他分享
首页 > 其他分享> > A - 约瑟夫环

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 2

Sample Output

3

Sponsor

普通的约瑟夫环写法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