题目描述
n 个人围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1 开始报数,到m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n-1 名小朋友,而该题是全部出圈。
输入格式
输入两个整数 n,m;
输出格式
输出一行 n 个整数,按顺序输出每个出圈人的编号。
输入输出样例
输入:10 3
输出:3 6 9 2 7 1 8 5 10 4
说明/提示,
n<=100;m>=1;
这道题的知识点是循环链表,需创建一个循环链表然后再对链表进行操作,思路很简单,但是在写代码时一定要注意细节,我在写的过程中把头指针和首节点弄混了,以至于代码越来越乱。直接上代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node* pNext;
}NODE,*PNODE;
PNODE creat_list();//创建循环链表
void out(PNODE pHead);//输出操作
int main()
{
PNODE pHead;
pHead=creat_list();
out(pHead);
return 0;
}
PNODE creat_list()
{
int n;
PNODE pHead=NULL;
PNODE p=pHead;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
PNODE q=(PNODE)malloc(sizeof(NODE));
q->data=i;
if(!pHead)//首节点没有数据为空,则为其赋上第一个数据
{
pHead=q;
p=q;
}
else
{
p->pNext=q;
p=q;
}
//若存在数据则在p的指针域存入新节点的地址,并让p移动到下一个节点的位置(即p始终为链表尾部)
}
p->pNext=pHead;//最后一个节点指针域存放第一个节点的地址
return pHead;
}
void out(PNODE pHead)
{
int n,i=1;
scanf("%d",&n);
PNODE p=pHead;
PNODE q;
while(p->pNext!=p)//当p->pNext==p时就只剩下最后一个节点了
{
while(i<n)//该循环的结果是使q永远在p的后一位上
{
q=p;
p=p->pNext;
i++;
}
q->pNext=p->pNext;//删除操作
printf("%d ",p->data);
free(p);
p=q->pNext;
i=1;
}
printf("%d",p->data);//输出最后一个节点
return ;
}
若有错误或疑问请及时提出!!