C语言有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
时间: 2023-12-23 18:52:40 浏览: 90
这个问题可以使用约瑟夫问题求解,最后留下的人的编号是:
f(n,m) = (f(n-1,m)+m) % n
其中,n 表示人数,m 表示报数到 m 就出圈。
根据题目描述,n 个人围成一圈,所以最后留下的人的编号可以用以下代码来求解:
```c
#include <stdio.h>
int josephus(int n, int m) {
int s = 0;
for (int i = 2; i <= n; i++) {
s = (s + m) % i;
}
return s;
}
int main() {
int n = 6, m = 3;
int last = josephus(n, m) + 1;
printf("Last person: %d\n", last);
return 0;
}
```
输出结果为:
```
Last person: 1
```
因此,最后留下的是原来第 1 号的那位。
相关问题
用c语言有 n 个人围成一圈,顺序排号。从第 1 个人开始报数(从 1 到 3 报数), 凡报到 3 的人退出圈子,问最后留下的是原来第几号的人。
这是一个经典的约瑟夫问题,可以用循环链表来实现。
具体实现如下:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
struct node* next;
} Node;
int main() {
int n = 10; // 假设有10个人
int k = 3;
Node* head = (Node*)malloc(sizeof(Node));
head->num = 1;
Node* p = head;
for (int i = 2; i <= n; i++) {
Node* q = (Node*)malloc(sizeof(Node));
q->num = i;
p->next = q;
p = q;
}
p->next = head; // 链接成循环链表
Node* pre = p; // pre指向最后一个节点
p = head; // p指向第一个节点
while (p->next != p) {
for (int i = 1; i < k; i++) {
pre = p;
p = p->next;
}
printf("出圈的人是:%d\n", p->num);
pre->next = p->next;
Node* q = p;
p = p->next;
free(q);
}
printf("最后留下的人是:%d\n", p->num);
free(p);
return 0;
}
```
输出结果为:
```
出圈的人是:3
出圈的人是:6
出圈的人是:9
出圈的人是:2
出圈的人是:7
出圈的人是:1
出圈的人是:8
出圈的人是:5
最后留下的人是:4
```
因此,最后留下的人是原来的第4号。
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。c语言
这是一个经典的编程问题,通常被称为“环形链表求剩余者”或“环形数组报数”。解决这个问题的一种常见方法是利用快慢指针,也称为Floyd算法。步骤如下:
1. 定义两个指针,一个初始指针`p1`指向第一个元素(索引为0),另一个初始化指针`p2`指向第二个元素(索引为1)。
2. `p1`每次向前移动3步,`p2`每次向前移动1步。因为报到3的人会退出,所以每三轮之后,`p1`和`p2`之间的相对位置就会保持不变,形成循环。
3. 当`p1`追上`p2`时(即`p1 % n == p2 % n`),这个公共的位置就是剩下的那个人的起始位置。由于`p2`是按照1、2、3的周期移动的,所以这个人就是原来的第`p2`+1号位置。
4. 为了得到最终的答案,需要加上这个人所处的圆周位置,即`(p1 - p2 + n) % n + 1`,这样就得到了原始编号。
C语言实现时可以使用变量和循环结构来模拟这个过程。注意处理边界情况,如果n是3的倍数,那么可能没有人剩下。
```c
#include <stdio.h>
int lastRemaining(int n) {
int p1 = 0, p2 = 1;
while (true) {
p1 = (p1 + 3) % n;
p2 = (p2 + 1) % n;
if (p1 == p2) {
break;
}
}
return (p2 + 1) % n + 1;
}
int main() {
int n; // 输入人数
printf("请输入人数:");
scanf("%d", &n);
int result = lastRemaining(n);
printf("最后留下的原先是第 %d 号位。\n", result);
阅读全文