约瑟夫环(使用C语言单向循环链表来解决)

题目描述
编号为1,2,…,n的n个人按顺时针方向围坐在一张圆桌周围,每人持有一个密码(正整数)。一

开始任选一个正整数m作为报数上限值,从第一个人开始按顺时针方向自1开始报数,报到m时停止报数,报m的那

个人出列,将他的密码作为新的m值,从他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列;如

此下去,直至圆桌周围的人全部出列为止。要求按出列顺序输出n个人的编号。

输入
第一行输入两个整数,依次表示人数n和初始化密码m,以空格间隔。

第二行依次输入n个整数,分别表示n个人的密码,以空格间隔。

输出
按出列次序输出每个人的编号,以空格间隔。
样例输入
7 20
3 1 7 2 4 8 4
样例输出
6 1 4 7 2 3 5


AC代码

#ifndef LIST_H
#define LIST_H

typedef struct node {
    int xuhao;
    int password;
    struct node * next;
}Node, *List;

#endif

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

int main(void)
{
    List head = (List)malloc(sizeof(Node));
    head->next = head;

    List prev = head;

    //定义总人数与初始密码
    int numbers, firstPassword;

    //临时数字
    int password;

    scanf("%d%d", &numbers, &firstPassword);

    for (int i = 1; i <= numbers; i++) {
        scanf("%d", &password);
        List pnew = (List)malloc(sizeof(Node));
        prev->next = pnew;
        pnew->xuhao = i;
        pnew->password = password;
        pnew->next = head;
        prev = pnew;
    }

    List p = head->next;
    prev = head;

    while (head->next != head) {
        if (firstPassword != 0) {
            password = firstPassword;
            firstPassword = 0;
        }
        for (int i = 0; i < password - 1; i++) {
            if (p->next == head) {
                p = p->next;
                prev = prev->next;
            }
            p = p->next;
            prev = prev->next;
        }
        if (p->next == head) {
            List t = p;
            password = p->next->password;
            printf("%d ", p->xuhao);
            prev->next = head;
            prev = head;
            p = head->next;
            free(t);
        }
        else {
            password = p->password;
            printf("%d ", p->xuhao);
            prev->next = p->next;
            List t = p;
            p = p->next;
            free(t);
        }

    }
    printf("\n");


    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40596811/article/details/82624680