P1996 约瑟夫问题

思路在代码注释中

代码如下

#include<iostream>
using namespace std;

const int MAXN = 100 + 5;
struct Node                //很明显是一个队列问题,很喜欢手撸队列(因为没学STL ,orz
{
    int num;            //用来保存数字( 1 ~ n 
};
struct Node queue[MAXN];    


int main()
{
    int n, m, k;        
    cin >> n >> m;
    k = n;            // 把 n 赋给 k,下面用 k 做判断, 这很重要,导致我debug一小时不知道自己哪错了 -.- 
    for(int i = 1; i <= n; i++) // 赋值 1 ~ n 
    {
        queue[i].num = i;
    }

    int j = 1;            // 用 j 来移动 要判断的数 
    while(n > 0)        // 因为数到 m ,就要输出,所以相当于输出 n 个数 
    {    
    
        for(int i = 1; i <= m; i++)        //开始整活 
        {
            if(j > k)        // 注意这里是 k,不是 n,因为下面 n 会变化。  
                j = j % k;    // 当 j 超过 k ,就要从头来 
            if(queue[j].num != 0 && i == m)    // 当 i == m 时,说明报数了 
            {
                cout << queue[j].num << " ";    // 输出 
                queue[j].num = 0;        // 将输出的数赋值为 0,方便下次跳过 
                n--;            // 输出一个数字后意味着要输出的数字少了一个,照应上方 
            }
            else if(queue[j].num == 0)    // 如果 遇到了 报过的数字,要将 i 多加的 1 减掉 
                i--;
            j++;            // 移动 j 
        }        
    }
    return 0;    // 总结 :一定注意 n 这个变量,开一个保存 n 的变量 k,因为 n 会变化
               // debug整了半天,想到这想给自己一巴掌 -.- 
}

Ps : 养成好习惯,以后每天一篇 小博客

原文地址:https://www.cnblogs.com/go-alltheway/p/13701751.html