约瑟夫环—华为试题

来源:互联网 发布:天勤网络 编辑:程序博客网 时间:2024/05/22 00:16

题目描述:

100个人围成一圈,每个人有一个编码,编号从1开始到100,他们从1开始依次报数,报到为M的人自动退出圆圈,然后下一个人接着从1开始报数,知道剩余的人数小于M,请问最后剩余的人在原先的编号是多少?例如输入M=3时,输出为:“58,91”,输入为M=4时,输出为:“34,45,97”。

这是一个典型的约瑟夫环问题,如何不考虑算法的复杂度,我们的最好的办法就是利用淘汰制来做,初始设置所有人都在圈中(都为‘1’),开始报数,淘汰每次报数的第M个人,淘汰的机制就设置为‘0’。我们所有人还是围成一圈,但是被置为‘0’的人是没有报数权利的,这样,每次淘汰一个人,我们都数数剩下多少人,当剩余人数少于M,游戏结束,程序如下:

//3  58 91//4  34 45 97#include<iostream>using namespace std;#include<string>#include<cstdlib>int main(){    int N=100;//人的总个数    int M;//间隔多少个人    string inputwhile(cin>>input){    bool *p=new bool[N+1];//[1……N]为true表示此人还活着    for (int i=1; i <= N; i++)        *(p+i)=true;    M=atoi(input.c_str());    if(M<=1 || M>=100)       { cout<<"ERROR!"<<endl;    cout<<endl;}else{    for (int i=1, j=0; ;i++)//i用来表示循环,j用来计算是不是第N个人    {        if (*(p+i))//此人还活着        {            j++;            if (j == M)            {                *(p+i)=false;                int K=0;                for(int k=1;k<=N;k++)                  {  if(*(p+k))                        K++;                }//K是剩余人数                if(K<M)                {                    for(int k=1;k<=N;k++)                      {  if(*(p+k))                            cout<<k<<endl;                    }                    break;                }                j=0;            }        }        if(i == N)            i=0;    }    delete []p;}    cout<<endl;}    return 0;}

运行结果如下:
这里写图片描述

原创粉丝点击