约瑟夫环

[题目链接](蓝桥杯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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值