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>
//结构体定义部分
typedef struct Node
{
int data;
struct Node *next;
}ListNode;
//创建链表,在链表的末端插入新的节点,建立链表
ListNode *CreateList(int n)
{
ListNode *head;//指向头结点指针
ListNode *p,*pre;
int i;
head=(ListNode *)malloc(sizeof(ListNode));//为头节点分配内存空间
head->data=1; //将头结点的指针域清空
pre=head; //先将头结点首地址赋给中间变量pre
for(i=2;i<=n;i++) //通过for循环不断加入新的结点
{
p=(ListNode *)malloc(sizeof(ListNode)); //为要插入的节点分配内存空间p指向新插入结点的首地址
p->data=i; //输入数
pre->next=p; //将p指向新结点插入链表也就是头结点指针域指向下个结点第一个结点就是p指向的,因为头结点内容为空
pre=p; //指向下一个结点
}
pre->next=head; //最后将最后一个结点的指针域清空了
return head; //返回这个链表的首地址
}
//输出链表
void Show(ListNode *h,int n)
{
ListNode *p;
p=h;
for(int i=0;i<n+2;i++)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
//删除
void DeleteList(ListNode *h, int i,int n)
{
ListNode *p,*q; //首先定义2个指向结点型结构体的指针
int j;
int data;
j=0;
p=h;
for(int k=0;k<n-1;k++)
{
for(j=0;j<(i-2);j++)
{
p=p->next;
}
q=p->next; /*q指向要删除的位置之前的那个结点指针域指向的地址q指向的结点就是要删除的结点*/
p->next=q->next;/*这个就是将要删除的结点的前面那个结点的指针域指向要删除的结点指针域中存放的下个结点的首地址从而实现了删除第i个结点的作用*/
data=q->data;
free(q); //释放q指向的结点
printf("%d ",data);
p=p->next;
}
q=p->next;
p->next=q->next;
data=q->data;
free(q); //释放q指向的结点
printf("%d",data);
}
//主函数
int main()
{
ListNode *h; //h指向结构体NODE
int i = 1,p, n;
scanf("%d%d",&n,&p);
h=CreateList(n);
// Show(h,n);
DeleteList(h,p,n);
return 0;
}