N个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。
请按退出顺序输出每个退出人的原序号。
输入格式:
输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。
输出格式:
按退出顺序输出每个退出人的原序号,数据间以一个空格分隔,但行尾无空格。
输入样例:
在这里给出一组输入。例如:
7 3
输出样例:
3 6 2 7 5 1 4
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *creat(int n)
{
struct node *head,*p,*tail;
int i;
p=(struct node*)malloc(sizeof(struct node));
p->data=1;
p->next=NULL;
head=tail=p;
for(i=2; i<=n; i++)
{
p=(struct node*)malloc(sizeof(struct node));
p->data=i;
p->next=NULL;
tail->next=p;
tail=p;//*****特别注意,连完之后要把手往后放一位
}
tail->next=head;
return (head);
}
int main()
{//输入,建表,操作,输出
int n,m;
struct node *head, *p,*q;//因为后面有进行删除操作,所以要定义两个手,p和q
scanf("%d %d",&n,&m);//输入数据
head=creat(n);//建立循环链表
q=head;//因为head需要保留,所以定义出一个手来进行操作
while(q->next!=head)//用q抓住head前的节点
{
q=q->next;
}
int con=0;//这是用来计数的
while(q->next!=q)//这个是结束条件,即q的后面还是q,即只有一个q时
{
p=q->next;//每次循环都用p抓住q后面的节点
con++;
if(con==m)//如果此次循环找到
{
printf("%d ",p->data);//打印
q->next=p->next;//删除
free(p);//释放
con=0;//重置
}
else q=p;//如果此次循环没找到,就将q往后挪一位,正好是p的位置
}
printf("%d\n",q->data);//最后把剩下的那个q已打印就行了
return 0;
}