解题思路:

既然约瑟夫环是一个环状结构,那我们应该可以使用双向链表来实现约瑟夫环,然后来解决问题。

首先我们先定义一个结构体变量,表示这个环上每一个结点,每个结点都有三个值,分别是表示这个结点的前一个结点的位置和后一个结点的位置,然后在需要一个变量来存储我们自己的编号。接下来就是初始化,把这个环构造出来,就是通过遍历,让每一个结点的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.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论