(C语言)约瑟夫环问题

题目描述


n
个人围成一圈,按顺序排号。从第一个人开始报数
,凡报到m的人退出游戏,然后下一个接着重新开始报数。比如n = 6,m = 3,当报到3时3号退出游戏,接着4号又从1开始报数……问最后留下的是原来第几号的那位
?

输入

输入有多组测试数据。

每组测试数据在一行中给出正整数n和m,(0<n<=100000, 0<m<=100000);

当读取到文件结尾时输入结束。

输出

对每组测试数据,在一行中输出最后留下来的人的初始编号

样例输入

20 5
10 4
10 3
100 373

样例输出

7
5
4
98

(个人认为这题对我的影响很大,因为第一次接触数据结构就是写的这个题目,刚开始看到链表的我是很不想活的,真的觉得这些东西都好恶心,因为我认为C语言中两个最难的结构体和指针包括在一起了,所以很蒙,于是又重新看了一下C语言的书,包括结构体和指针,然后我发现其中的结构体的别名和结构指针有一些是可以省略,有一些是可以替换的,当然都是本人亲自实践了的,下面代码中注释的地方都是可以替换或者等价的地方,然后说说这个题吧,这个题用的是循环链表,就是将链表的尾结点一直指向链表的头结点,然后期间包括链表的初始化和插入删除的一些基本的操作,于是当循环到出局编号的时候将该结点删除同时释放掉 free()函数,然后继续对这个循环链表遍历,当链表中只有一个结点的时候退出循环,然后输出该结点的data即可,所以说,理解了链表的基本操作之后哦就很简单,而且我发现链表真的很有用,不管是在实用价值还是ACM中都是一个很好的方法)

#include<stdio.h>

#include<stdlib.h>

typedef struct Node{ // 构建链表结构体

int data;

struct Node *next;

}JoseNode,*PNode;  //JoseNode *==PNode

void InitNode(PNode *h){  //初始化链表

(*h)->next = (*h);

}

int InsertNode(JoseNode *h,int pos,int x) {  //链表的插入数据

PNode p=h,q;  //JoseNode *p=h,*q;

int i=1;

if (pos == 1) {

p->data=x;

p->next=p;

return 0;

}

while (i<pos-1) {

p=p->next;

i++;

}

q=(JoseNode *)malloc(sizeof(JoseNode));  //q=(PNode)malloc(sizeof(JoseNode));

q->data=x;

q->next=p->next;

p->next=q;

return 0;

}

void deNode(PNode h,int m,int k) {  //在链表中删除某个结点

PNode p=h,q;

int i=0;

while (m>1) {

for (i=1; i<k-1; i++) 

p=p->next;

q=p->next;

p->next=q->next;

free(q);

p=p->next;

m–;

}

printf(“%d\n”,p->data);

}

int main(){

int N,k;

int i;

while(scanf(“%d%d”,&N,&k)!=EOF) {

JoseNode *h=(PNode)malloc(sizeof(JoseNode));  //PNode h=(PNode)malloc(sizeof(JoseNode));

InitNode(&h);

for (i=1; i<=N; i++)

InsertNode(h,i,i);

if (k>1)

deNode(h,N,k);

else

printf(“%d\n”,&N);

}

return 0;

}

    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/yimo_fan/article/details/70477672
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞