Description

话说二哥当年学习数据结构的时候遇到了那道猴子报数的题目,其实这就是经典的约瑟夫问题。

可是当年的二哥还是个毛头小子,只会用模拟的方法,而其他同学却使用了一些令二哥完全摸不到头脑的方法。

……二哥一怒之下改了题目……

话说当年花果山的猴子要选大王,选举办法如下:

所有猴子按1-M编号围坐一圈,二哥站在圈中心,由二哥指定一个整数Kn,

之后猴子们从1号开始按顺序报数,报到Kn的猴子退出到圈外,二哥再报出一个整数Kn+1,

然后由刚刚退出的猴子的下一只猴子再开始报数,如此循环报数,直到圈内只剩下一只猴子时,这只猴子就是大王。

由于二哥希望通过此种方法控制花果山,所以现在二哥把他制定的整数序列告诉你,希望你帮他预先算出那只猴子会成为大王。

Input Format

第一行 一个整数M,表示一共有M只猴子

第二行到第M行,每行一个整数 表示二哥即将指定的M-1个整数。这些数都大于0。

Output Format

一个整数,表示最后剩下那只猴子的编号。

Hint

对于40%的数据,M<=1000, K<=1000

对于70%的数据,M<=10000, K<=10000

对于100%的数据,M<=10000, K<=100000000

Sample Input

5
1
2
3
4

Sample Output

4



 1.链表模拟法 很简单 也能AC 优化就是对K进行取余操作
但是要注意一点就是 因为我习惯了用1 2 3 来做代号 在取余时可能会出现K恰好是cnt的倍数 所以要进行单独处理 这点可以用换代号为 0 1 2...来解决
模拟法代码:
#include <iostream>
using namespace std;

int front[10000+10];
int nex[10000+10];
//模拟法
void out(int x){
    nex[front[x]] = nex[x];
    front[nex[x]] = front[x];
}

int main(int argc, char const *argv[])
{
    int M;
    cin>>M;
    for (int i = 1; i <= M; ++i)
    {
        front[i] = (i==1) ? M : i-1;
        nex[i] = (i==M) ? 1 : i+1;
    }
    int cur = 1;
    int cnt = M;
    int K;
    while(1){
        cin>>K;
        K %= (cnt);
        if(K==0)
            K+=cnt;
        for (int i = 0; i < K-1; ++i)
        {
            cur = nex[cur];
        }
        out(cur);
        cur = nex[cur];
        cnt--;//出去一只猴子
        if(cnt == 1){
            cout<<cur<<endl;
            break;
        }
    }

    return 0;
}
链表模拟法

相关文章: