• 7.9 约瑟夫问题—数组实现


    【问题描述】
      有m个人,其编号分别为1-m。按顺序围成一个圈,现在给定一个数n,从第一个人开始依次报数,报到n的人出圈,

    然后再从下一个人开始继续从1开始依次报数报到n的人再出圈,…如此循环,直到最后一个人出圈为止。编程输出所有人出圈的顺序。

    输入格式
      一行两个正整数m和n,之间用一个空格隔开,1≤m<100,1≤n≤32767。
    输出格式
      输出m行,每行一个正整数,表示依次出圈的人的编号。
    输入样例
    85
    输出样例

    5 

    2 

    8  

    7  

    1  

    4  

    6  

    3
    问题分析
      定义bool型数组p,表示每个人在圈中的状态。假设p[i]为true表示第i个人还在圈中,
    p[i]为 false表示第i个人已出圈。模拟报数的过程,从第一个人(i=1)开始报数,定义计数
    器j,初始化为0,如果p[i]为tmue,则j加1,当j为n时,报到的这个人出圈(p[i]=false,且
    j=0),…直到所有人都已出圈。程序实现时,另外设计一个计数器t,记录圈中的剩余人数,
    初始化为m。

    题解代码:

    #include<iostream>
    #include<cstring>
    #include<list>
    using namespace std;
    int m,n;
    list<int> l;
    int main(){
     scanf("%d%d",&m,&n);
     int cnt1=m,cnt2=1;//cnt2表示计n数
     bool p[101];
     memset(p,false,sizeof(p));
     int i=0;//i表示指针
     while(cnt1){
      if(i==m) i=0;
      if(p[i]==true){
       i++;
       continue;
      }
      if(cnt2==n){
       cnt2=1;
       p[i]=true;
       cnt1--;
       printf("%d\n",i+1);
       i++;
      
      }
      else{
       i++;
       cnt2++;
      }
     }
     return 0;
    }

    题解思路:

      这道题的思路即为构造一个环,使得对应坐标指针i能在队列中从头到尾的一次又一次游走,我们先定义i作为1到m的指针,定义cnt1为元素个数,cnt2为每次计数1到n时的值,即约瑟夫环1到n的指针。定义一个bool型数组p,代表当前元素是否已出列。

    具体实现:用一个while循环判断cnt1元素个数是否为0,循环中每出列一个元素,则cnt1--,若cnt1==0则元素已全部出列,跳出循环。

    while中,判断i的值,若i==m说明已到达结尾外,需返回队列开头,令i=0。(注意,我们取得元素下标为0到m-1),若p[i]==true,说明已出列,则continue进入循环下一阶段,若p[i]==false,则在队列中,cnt2为计数1到n中的第几个,若为n说明应当删去,cnt2=1,printf输出对应的值;若cnt2小于n,则cnt2++,进入下次循环

    (注意,我的每次运算中i与cnt2指针的值都在该循环阶段之前已计算出,计算前与计算后的逻辑关系同学们需要好好思索,搞清楚)

  • 相关阅读:
    查询URL字符串参数
    location 对象
    css3 文字特效
    functionDo
    css3 渐变
    [LeetCode][Java]Peeking Iterator
    [LeetCode][JavaScript]Expression Add Operators
    [LeetCode][JavaScript]Different Ways to Add Parentheses
    [LeetCode][JavaScript]Move Zeroes
    [LeetCode][JavaScript]Binary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/cxs070998/p/11156920.html
Copyright © 2020-2023  润新知