用C语言编码有 N 个人围成一圈,顺序排号,从第一个人开始报数(1 至 M 报数) ,凡 是报到 M 的人退出圈子。求最后留下的人原来排在第几号。
时间: 2024-11-30 09:22:27 浏览: 64
这是一个经典的动态规划问题,可以使用环形数组和模拟的方式来解决。以下是基本的算法步骤:
1. 初始化一个大小为 N 的整型数组 `circle`,表示每个人的位置。因为是逆时针方向报数,所以数组下标从 0 到 N-1 表示第 1 个人到最后一个人。
2. 创建一个变量 `currentIndex` 用于追踪当前正在报数的人,初始值为 0(代表第 1 个人)。
3. 设置一个计数器 `count` 从 1 开始,这是报数的过程。
4. 进入一个循环,直到计数器大于 M 并且 `currentIndex` 不等于 0(即还有人在圈内)。在循环内部:
a. 更新 `circle[currentIndex]`,使其加 1。
b. 如果 `circle[currentIndex]` 能被 M 整除,则这个人需要退出圈子,将 `currentIndex` 设为下一个位置(`(currentIndex + 1) % N`)并减少剩余人数(减去 `count`)。
c. 否则,继续报数,`count` 加 1。
5. 当循环结束时,`currentIndex` 对应的就是最后留下的那个人原来的编号。
下面是一个简单的 C 语言实现的例子:
```c
#include <stdio.h>
#include <stdbool.h>
int findLastPerson(int N, int M, int* circle) {
int currentIndex = 0;
int count = 1;
while (true) {
circle[currentIndex]++;
if (circle[currentIndex] == M || !circle[currentIndex]) {
// 如果是M倍或到达第一个位置,跳出
currentIndex = (currentIndex + 1) % N;
count--;
if (!count) break; // 如果所有人都走了,结束
} else {
count++;
}
}
return currentIndex;
}
int main() {
int N, M;
scanf("%d%d", &N, &M);
int* circle = malloc(N * sizeof(int)); // 初始化环形数组
for (int i = 0; i < N; i++) {
circle[i] = 0;
}
int lastPersonIndex = findLastPerson(N, M, circle);
printf("最后剩下的人原来排在第 %d 号。\n", lastPersonIndex + 1); // 因为数组是从 0 开始的
free(circle); // 释放内存
return 0;
}
```
阅读全文