约瑟夫环

正文索引 [隐藏]

题目描述:

N个人围成一圈顺序编号,从1号开始按1、2、3……顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。 请按退出顺序输出每个退出人的原序号。

输入描述:

输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。

输出描述:

按退出顺序输出每个退出人的原序号,数据间以一个空格分隔,但行尾无空格。

输入样例:

在这里给出一组输入。例如:
7 3

输出样例:

3 6 2 7 5 1 4

解题思路:

经典的约瑟夫环问题,我是采用队列来进行求解的,先把n个人全部入队,每次从cnt=1开始数,若数到了p则出队并令cnt=0,否则将这个人的编号继续推入队尾进行循环,直到队列为空为止。

AC代码:

#include <bits/stdc++.h>
using namespace std;
#define Up(i,a,b) for(int i = a; i <= b; i++)
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n,p;
    cin >> n >> p;   //n个人,p出圈
    int cnt = 0;
    queue<int> q;
    Up(i,1,n)
    {
        q.push(i);
    }
    bool virgin = true;
    while(!q.empty())
    {
        if(++cnt == p)
        {
            if(virgin)
            {
                cout << q.front();
                virgin = false;
            }
            else cout << " " << q.front();
            q.pop();
            cnt = 0;
        }
        else
        {
            q.push(q.front());
            q.pop();
        }
    }
    return 0;
}