题目描述
n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 11 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
题目分析:
- n个人,编号从1到n,都将他们存放在一个圆内。
- 从第一个人开始报数,报到m的人出列,输出其编号;
- 然后从出列的人下一个人开始重新报数,报到m的人又出列,继续统计并输出其编号;
- 依此规律重复进行直到统计的人数与总人数相等时,结束循环,输出完毕。
我们在这里使用数组的方式来解决:
先定义一个数组,最开始将所有的元素初始化为0,0代表一开始所有人都在圈内,一旦某个人出局,将其对应的数组元素的值设为1,代表他以出圈;
N:代表N个人
M:从1开始,报到M这个数的人出局
i:既代表数组的下标,也代表每个人的编号
count:用来计数,从0开始,一旦k的值达到M,代表当前这个人需要出局,并且k的值需要重新置为0,这样才能找到所有需要出局的人
index:用来标记每次循环的编号,使其控制在有效的编号之内
结果代码:
#include <stdio.h>
#include <stdbool.h>
void fun(int n, int m)
{
int c[n];
int count = 0; //标记报道的个数
int index = 0; //标记编号
for(int i=0;i<n;i++)
c[i]=1;
for (int i = 0; i < n - 1; i++)
{
while (count < m)
{
if (c[index]!=0)
{
count++;
}
index = (index + 1) % n;
}
c[(index - 1+n ) % n] = 0;//防止最后一个人出错
printf("%d ", (index - 1+n) % n + 1);
count = 0;
}
for (int i = 0; i < n; i++) {
if (c[i]!=0) {
printf("%d\n", i + 1);
break;
}}}
int main() {
int n, m;
scanf("%d %d", &n, &m);
fun(n, m);
return 0;
}
总结:
解决该题使用数组加以标记的形式,根据标记的内容来判断所存在状态,n个人,编号从1到n,给他们全部赋值为1。开始报数,报到m的人将标记赋值为0,代表他已经不在计算范围内,统计加一;依此规律重复进行,当统计的人数变量与总人数相等时,结束循环,输出完毕。