Description
編號是1,2,……,n的n個人按照順時針方向圍坐一圈,每個人持有一個密碼(正整數)。一開始任選一個正整數作爲報數上限值m,從第一個仍開始順時針方向自1開始順序報數,報到m時停止報數。報m的人出列,將他的密碼作爲新的m值,從他的順時針方向的下一個人開始重新從1報數,如此下去,直到所有人全部出列爲止。請設計一個程序輸出出列順序。
提示:存儲結構採用不帶頭結點的循環單鏈表,結點結構如下:
typedef struct Node
{ int ID;
int password;
struct Node *next;
}LNode,*LinkList;
要求:
(1)編寫建立循環單鏈表的函數,依次輸入每個人的ID和password建立不帶頭結點的循環單鏈表。
(2)編寫函數,按照規則依次刪除相應的元素。
(3)main()函數調用(1)和(2)中的函數,輸出約瑟夫序列。
注意:m=1 時需要特殊處理。
Input
輸入n
輸入m
第1行爲n
第2行爲m
接下來每行表示每個人的ID和password
Output
依次輸出出列者的ID
每輸出一個人的ID換行。
Sample Input
8 4 1 3 2 1 3 9 4 2 5 4 6 7 7 4 8 6
Sample Output
4 6 7 3 5 8 2 1
HINT
注意:處理m=1的特殊情況。
輸出最後一個人的ID後,也要換行。
/*約瑟夫環*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{ //定義循環鏈表
int id;
int password;
struct LNode * next;
}LNode,*LinkList;
LinkList CreatList(LinkList head,int n)
{
int i;
LinkList p,q;
head = (LinkList)malloc(sizeof(LNode));
q = head;
scanf("%d %d",&q->id,&q->password);
for(i = 2;i<=n;i++)
{
p = (LinkList)malloc(sizeof(LNode));
scanf("%d %d",&p->id,&p->password);
q->next = p;
q = p;
}
p->next =head;
return head;
}
/*
void Display(LNode *pHeader)
{
LNode *pCurNode;
pCurNode=pHeader;
printf("%d ",pCurNode->password);
while(pCurNode->next!=pHeader)
{
pCurNode = pCurNode->next;
printf("%d ",pCurNode->password);
}
}*/
void Joseph(LinkList head,int k)
{
LinkList p,q;
int m,i;
p = head;
m =k;
/*
for(i = 1;i<k;i++)
{
p = p->next;
}*/
// q = p;
while(p->next!=p)
{
for(i=1;i<m;i++)
{
q=p;
p = p->next;
}
m = p->password;
printf("%d\n",p->id);
q->next = p->next;
free(p);
p = q->next;
}
printf("%d\n",p->id);
free(p);
}
int main()
{
int k,n;
LinkList L,head;
L = NULL;
scanf("%d",&n);
scanf("%d",&k);
head = CreatList(L,n);
//Display(head);
Joseph(head,k);
return 0;
}