解题思路:
既然约瑟夫环是一个环状结构,那我们应该可以使用双向链表来实现约瑟夫环,然后来解决问题。
首先我们先定义一个结构体变量,表示这个环上每一个结点,每个结点都有三个值,分别是表示这个结点的前一个结点的位置和后一个结点的位置,然后在需要一个变量来存储我们自己的编号。接下来就是初始化,把这个环构造出来,就是通过遍历,让每一个结点的pre指向前一个结点,next指向后一个结点的位置,通过遍历,当我们数到要出局的人时,把前一个结点的next指向这个结点的后一个,然后把后一个结点的pre指向这个结点的前一个,这样就完成删除操作了。当最后只剩下一个结点时,那么就是结束了,它的pre和next都是自己,那么就可以退出循环,最后输出它的编号即可
(大一学生,水平不够,如果有哪里错误的话,请大家指出,谢谢!)
注意事项:
计数时每次记完要记得清零;
考虑当n==1或者m==1时的情况,应该都是没有活下来的
参考代码:
#include<stdio.h>
#include<stdlib.h>
struct node {
int pre;//前一个人的位置
int next;//后一个人的位置
int num;//当前编号
};
int main() {
int n,m;
node flag[100];
while (scanf("%d%d", &n, &m)!=EOF) {
if (n == 1 || m == 1)printf("%d\n", 0);
else {
for (int i = 1; i <= n; i++) {//初始化
flag[i].pre = i - 1;
flag[i].next = i + 1;
flag[i].num = i;
if (i == 1)
flag[i].pre = n;
if (i == n)
flag[i].next = 1;
}
int count = 0; int x;
for (int i = 1;; i = flag[i].next) {//i从1开始,每次进入下一个的编号
count++;//进入一次循环增加
if (count == m) {//如果等于了报道的数,那么就出局
flag[flag[i].pre].next = flag[i].next;//前一位的后指针指向这一位的后一位
flag[flag[i].next].pre = flag[i].pre;//这一位的后一位的前指针指向这一位的前一位
count = 0;//重新计数
}
if (flag[i].next == i && flag[i].pre == i) {//前指针后指针都指向自己,说明只剩一人,那么输出
x = i;
break;
}
}
printf("%d\n", flag[x].num);
}
}
return 0;
}
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复