【问题描述】m个人围成一圈,1,2,3循环报数,报到3的人退出,并将退出的序号依次存到数组p中,包括最后一个人的序号。输出最后退出的是原来的第几号(最初的序号,以1起始)。若m=6,则最后退出的是1号,退出的顺序是 : 3 6 4 2 5 1;若m=10,则最后退出的是4号,退出顺序是: 3 6 9 2 7 1 8 5 10 4;若m=100,则最后退出的是91号,退出顺序是: 3 6 9……100 58 91。 编写函数int fun(int m ,int p[ ])实现上述功能,返回m个人中最后退出人的序号,并将退出的序号顺序写入p指向的数组中。在主函数中输入人数,调用fun后输出实参数组中保存的退出序号。每行输出10个数据。 本问题限定人数m不超过200人。 【输入形式】输入人数(不大于200的整数) 【输出形式】输出最后退出人的序号,以及退出的顺序
时间: 2023-06-10 18:07:13 浏览: 46
以下是一种解法:
```c
#include <stdio.h>
#define MAXN 205
int fun(int m, int p[]) {
int a[MAXN], i, j, k = 0;
for (i = 0; i < m; i++) {
a[i] = i + 1; // 初始化
}
i = -1; // 从第0个人开始报数
while (k < m) { // k 表示已经退出的人数
int count = 0;
while (count < 3) { // 报数
i = (i + 1) % m;
if (a[i]) { // 如果这个人还没有退出
count++;
}
}
p[k++] = a[i]; // 记录退出的人
a[i] = 0; // 标记为已退出
}
return a[(i + m) % m]; // 最后一个退出的人
}
int main() {
int m, p[MAXN], i;
scanf("%d", &m);
int last = fun(m, p);
printf("%d\n", last);
for (i = 0; i < m; i++) {
printf("%d ", p[i]);
if ((i + 1) % 10 == 0) { // 每行输出10个数
printf("\n");
}
}
if (i % 10 != 0) { // 最后一行没满10个数,换行
printf("\n");
}
return 0;
}
```
思路解析:
我们可以用一个数组 `a` 来表示每个人的状态,初始时都为 1,表示还没有退出。然后我们从第 0 个人开始报数,每报到 3 就将当前这个人标记为已退出,直到所有人都退出为止。
在这个过程中,我们用一个计数器 `k` 来记录已经退出的人数,每次退出一个人时,就将他的编号存入数组 `p` 中,方便后面输出。
最后,剩下的最后一个人就是最后退出的人,返回他的编号即可。
注意,由于是围成一圈,所以当 i 超过最后一个人时,需要对它取模 m,才能得到正确的位置。另外,输出时需要每行输出 10 个数,因此需要特别处理一下输出格式。