两种约瑟夫环的非递归解决方法
1.题目描述:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
主要思想:
- 先定义一个长度的数组,其值为0或是1,1表示该人在队列中,0表示已经出列,而数组的下标表示该人的编号。
- 要设置一个计数器s,来表示报数的值,如果与m相等的话,计数器清零,其对应的数组中下标为t的要记为0,表示出列。
- 还要设置一个f,来表示出去的人数,当初去的人与总人数相等时,循环结束。
- 变量t表示循环不断地在进行着,t的值即是当前的人的编号,当t>n时,有要将t=1,因为输入的数组是有长度限制的。
本方法采用数组
#include<stdio.h>
int main()
{
//数组a来判断这个人是否出列
int a[100000]={1};
for(int i=0;i<101;i++)
a[i]=1;
int n,m,i,f=0,t=0,s=0;
scanf("%d",&n);
scanf("%d",&m);
while(1)
{
++t;
if(t>n)
t=1;
if(a[t]==1)//要判断其是否出列,才能让计数器增加
s++;
if(s==m)
{
s=0;//计数器清零
printf("%d ",t);
a[t]=0;//出列
f++;//出去的人数加一
}
if(f==n)//满足循环退出的条件
break;
}
}
2.题目描述:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。每个人手持一个密码,从编号为k的人开始报数,数到与密码相等时,那个人出列;他的下一个人又从1开始报数,数到该人密码相等时,那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列.
主要思想:
- 再设置一个数组用来存放每个人的密码。
- 思想与上一题一样,就是将m换成每人所持的密码。
#include<stdio.h>
int main()
{
//数组a来判断这个人是否出列
int a[100000]={1};
for(int i=0;i<101;i++)
a[i]=1;
int b[100001];
int n,m,i,f=0,t=0,s=0;
int x=0;//mima
scanf("%d",&n);
scanf("%d",&b[0]);
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
while(1)
{
++t;
if(t>n)
t=1;
if(a[t]==1)
s++;
// printf("%d ",b[x]);
if(s==b[x])
{
s=0;
printf("%d ",t);
a[t]=0;
f++;
x=t;
}
if(f==n)
break;
}
}