0
点赞
收藏
分享

微信扫一扫

约瑟夫环

杏花疏影1 2022-04-01 阅读 72
c++

[题目链接](蓝桥杯2018年第九届真题-约瑟夫环 - C语言网)


###

题目描述

n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数。
(报数是从1报起)当报到 k 的时候,这个人就退出游戏圈。下一个人重新从1开始报数。
求最后剩下的人的编号。这就是著名的约瑟夫环问题。

本题目就是已知 n,k 的情况下,求最后剩下的人的编号。

输入

题目的输入是一行,2个空格分开的整数n, k

约定:0 < n,k < 1百万

输出

要求输出一个整数,表示最后剩下的人的编号。

样例输入

10 3

样例输出

4

> x


### 思路

> 1. 每次删除了一个数之后,就重新编号,找出原来的和新的编号的关系。

新: 1,        2 ,      3

旧:m + 1,  m + 2,  m + 3   

 得到f(新的+m)%n ==f(n-,m)%10又因为计数从一开始,所以m,n需要减一得到(f(n - 1, m) + m - 1) % n + 1;

    
### 坑点

> 1. 用其他的算法会超时
 


### 算法:递归


#### 时间复杂度

$时间限制: 1Sec 内存限制: 128MB 


#### 实现步骤

> 1. 先找出新的与旧的编号对应关系
> 2. 再推出公式


#### 代码

```#include<string>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
long long int a[1000005];
int f(int n,int m)
{
    if(n==1)
    {
        return n;
    }
    else
    {
        return (f(n-1,m)+m-1)%n+1; //推出的公式
    }
}
int main()
{
    long long int n,k;
    cin>>n>>k;
    cout<<f(n,k);
    return 0;
}


```
### 总结:主要找出新的与旧的编号对应关系

> x

举报

相关推荐

0 条评论