有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。c语言
时间: 2023-12-23 20:50:46 浏览: 64
可以使用循环链表来模拟这个过程。
具体实现方法是,首先创建一个循环链表,其中每个节点代表一个人,节点中保存了这个人的编号和是否已经退出的状态。然后从第一个人开始报数,每报到3就将这个人从链表中删除。直到只剩下一个人为止,这个人就是最后留下的人。
以下是具体的 C 语言实现代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点类型
typedef struct Node {
int num; // 编号
int is_out; // 是否已退出
struct Node *next; // 指向下一个节点的指针
} Node;
int main() {
int n, count = 0, left = 0;
Node *head, *tail, *p, *q;
// 读入人数 n
printf("请输入人数:");
scanf("%d", &n);
// 创建循环链表
head = tail = (Node *)malloc(sizeof(Node));
head->num = 1;
head->is_out = 0;
for (int i = 2; i <= n; i++) {
p = (Node *)malloc(sizeof(Node));
p->num = i;
p->is_out = 0;
tail->next = p;
tail = p;
}
tail->next = head; // 将链表首尾相连,形成循环链表
// 开始报数
p = head; // p 指向当前报数的人
while (left < n - 1) { // 只要还剩下 1 个人没有退出,就继续报数
if (!p->is_out) { // 如果这个人没有退出
count++; // 报数加一
if (count == 3) { // 如果报数达到 3
p->is_out = 1; // 将这个人标记为退出状态
count = 0; // 报数清零
left++; // 剩余人数减一
printf("%d 号退出\n", p->num); // 输出退出的人的编号
}
}
p = p->next; // 指向下一个人
}
// 输出最后留下的人的编号
for (q = head; q->is_out; q = q->next); // 找到最后留下的人
printf("最后留下的是 %d 号\n", q->num);
return 0;
}
```
注意,这个程序的输出结果中,先输出的是退出的人的编号,最后输出的是最后留下的人的编号。如果需要改变输出顺序,可以在程序中适当调整输出语句的位置。
阅读全文