本题是我做的第一道数据结构,以此为开端记录我的计算机学习之路吧~
从洛谷上的题目如下:
用c语言实现
题目描述
n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 11 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n−1 名小朋友,而该题是全部出圈。
输入格式
输入两个整数 n,m。
输出格式
输出一行 n 个整数,按顺序输出每个出圈人的编号。
输入输出样例
输入 #1复制
10 3
输出 #1复制
3 6 9 2 7 1 8 5 10 4
说明/提示
1≤m,n≤100
本题的思路也很简单粗暴,建立一个循环链表,哪个人到了削哪里(不是)
但是有一个问题是我们建立链表的时候会有一个空的头结点,当尾部连接的时候,会和头结点连接,这就导致了每次转圈杀人的时候都要考虑是不是该跳过头结点
额…………
为啥不直接把头结点也写入数据啊?
我当时还傻乎乎的考虑如何跳头的代码
以下是小白刚刚写的代码(大佬勿喷);
#include<stdlib.h>
#include<stdio.h>
typedef struct lnode
{
int sign;
struct lnode* next;
} lnode,*linklist;
void initlist(linklist* l)
{
(*l) = (linklist)malloc(sizeof(lnode));
(*l)->next = NULL;
}
void creatlistR(linklist* l,int n)//尾插法
{
(*l) = (linklist)malloc(sizeof(lnode));
(*l)->next = NULL;
(*l)->sign=1;
linklist p, r;
r = (*l);
for (int i = 2; i <=n; i++)
{
p = (linklist)malloc(sizeof(lnode));
r->next = p;
p->next = (*l);
p->sign = i ;
r = p;
}
}
int dellist(linklist* l, int m,int n)//相当于删除结点的操作
{
int count=n;
int e;
linklist p,q;
p = *l;
for (int i = 1; i <m-1; i++)
{
p = p->next;
}
e = p->next->sign;
q = p->next;
p->next = q->next;
free(q);
count--;
printf("%d ",e);
p=p->next;
if(count>0)
return dellist(&p,m,count);//使用递归,并用count来记录是否全部出圈
else
return 0;
}
int main()
{
int n,m;
linklist l;
initlist(&l);
scanf("%d %d", &n,&m);
creatlistR(&l, n);
dellist(&l,m,n);
return 0;
}