约瑟夫环

n个数字(1,2,3…,n)形成一个圆圈,从数字1开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数 字的下一个继续删除第m个数字。
求出在这个圆圈中剩下的最后一个数字。

Input

n=9

m=5

Output

The last one is 8

解题思路:

利用队列是线性的关系,将m之前的数重新排入队尾,而第m个则被删除

 1 #include<stdio.h>
 2 #include<queue>
 3 using namespace std;
 4 int main()
 5 {
 6     queue<int>q;
 7     int n,m,i,a;
 8     scanf("%d%d",&n,&m);
 9     for(i=1; i<=n; i++)
10     {
11         q.push(i);///入队
12     }
13     while(q.size()>1)///1为最后剩下的人数
14     {
15         for(i=0;i<m;i++)
16         {
17             a=q.front();///返回首元素
18             q.pop();///删除首元素
19             if(i<m-1)
20             {
21                 q.push(a);///压入队尾
22             }
23         }
24     }
25     printf("%d
",q.front());
26     return 0;
27 }

另外附上当时使用虚拟数组来实现的约瑟夫环的代码:

#include<stdio.h>
int main()
{
    int n,m,i,j,a[10000],count;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1; i<=n; i++)
        {
            a[i]=i;
        }
        j=n;///j圈中剩余人数
        count=0;
        i=1;///从1开始报数
        while(j>1)///只剩下一个人为止
        {
            if(a[i]!=0)
            {
                count++;
                if(count==m)///报道数
                {
                    a[i]=0;///退出圈子
                    count=0;///清零重新从1开始报数
                    j--;///剩余人数减一
                }
            }
            i++;///下一个人准备报数
            if(i>n)///若越过最后一人
                i=1;///转到第一人
        }
        for(i=1; i<=n; i++)
        {
            if(a[i]!=0)
                printf("%d
",a[i]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wkfvawl/p/8671818.html