好玩的约瑟夫环:有M个人,编号分别为1到M,玩约瑟夫环游戏,最初时按编号顺序排成队列;每遍游戏开始时,有一个正整数报数密码N,队列中人依次围坐成一圈,从队首的人开始报数,报到N的人出列,然后再从出列的下一人开始重新报数,报到N的人出列;重复这一过程,直至所有人出列,完成一遍游戏,所有出列的人形成新队列;游戏可能玩很多遍,每遍有新报数密码。求若干遍游戏完成后队列次序。题目输入包括若干个正整数(至少1个),第一个正整数为玩游戏人数M,后续每个正整数为每遍游戏报数密码,报数密码可能为1,题目要求按出队列顺序输出他们的编号。
输入样例:
10 3 5 2
输出样例:
4 6 5 2 9 1 3 7 8 10
代码如下:
#include
#include
struct Node {
int data;
struct Node *next;
};
//createNew
struct Node *createNew()
{
struct Node *p;
p = (struct Node *)malloc(sizeof(struct Node));
p -> next = NULL;
return p;
};
//build创建循环链表
void build (struct Node **pp, int m) {
struct Node *phead, *pnew, *pold;
phead = *pp;
pold = phead;
int i;
for(i = 1; i <= m; i++) {
pnew = createNew();
pnew -> data = i;
pold -> next = pnew;
pold = pold -> next;
}
pold -> next = phead -> next;
}
//append添加人数
void append(struct Node **pp1, struct Node **pp2, int n) {
struct Node *phead1, *phead2, *pold, *pafter, *pnext;
phead1 = *pp1;
phead2 = *pp2;
pold = phead1 -> next;
pafter = pold -> next;
pnext = phead2;
while(phead1 -> next){
if(n >= 3) {
for(int i = 0; i < n - 2; i++) {
pold = pold -> next;
pafter = pold -> next;
}
}
else if(n == 2) {
pafter = pold -> next;
}
else if(n == 1) {
pold = phead1;
pafter = pold -> next;
}
//phead2未存储数据
if(!phead2 -> next) {
phead2 -> next = pafter;
pnext = pnext -> next;
}
//printf("pnext = %dn",pnext -> data);
else {
pnext -> next = pafter;
pnext = pnext -> next;
}
pold -> next = pafter -> next;
pold = pold -> next;
//printf("pnext->next = %dn",pnext -> data);
//printf("pold = %dn",pold -> data);
//只剩下一个人n >= 2跳出循环的条件
if(pold == pold -> next) {
pnext = pold;
pnext -> next = NULL;
break;
}
//n == 1跳出循环的条件
if(n == 1) {
if(pafter -> next -> data == phead2 -> next -> data) {
pafter -> next = NULL;
break;
}
}
}
}
//print
void print(struct Node *p, int m)
{
for(int i = 0; i < m; i++) {
printf("%4d",p -> next -> data);
p = p -> next;
}
}
void repeat(struct Node **pp) {
struct Node *phead, *pnext;
phead = *pp;
pnext = phead -> next;
while(pnext -> next) {
pnext = pnext -> next;
}
pnext -> next = phead -> next;
}
//destroy
void destroy(struct Node *p)
{
struct Node *pnext;
while(p) {
pnext = p -> next;
free(p);
p = pnext;
}
//printf("destroyed!");
}
int main()
{
//新建两个链表的头节点
struct Node *phead1, *phead2;
phead1 = createNew();
phead2 = createNew();
//输入人数
int m;
scanf("%d",&m);
//创建循环链表
build(&phead1,m);
//第一次游戏
int x;
scanf("%d",&x);
append(&phead1,&phead2,x);
//循环游戏
while(getchar() == ' ') {
phead1 = phead2;
repeat(&phead1);
phead2 = createNew();
scanf("%d",&x);
append(&phead1,&phead2,x);
}
//打印
print(phead2,m);
//销毁
destroy(phead2);
return 0;
}
4 6 5 2 9 1 3 7 8 10代码如下:
#include#include struct Node { int data; struct Node *next; }; //createNew struct Node *createNew() { struct Node *p; p = (struct Node *)malloc(sizeof(struct Node)); p -> next = NULL; return p; }; //build创建循环链表 void build (struct Node **pp, int m) { struct Node *phead, *pnew, *pold; phead = *pp; pold = phead; int i; for(i = 1; i <= m; i++) { pnew = createNew(); pnew -> data = i; pold -> next = pnew; pold = pold -> next; } pold -> next = phead -> next; } //append添加人数 void append(struct Node **pp1, struct Node **pp2, int n) { struct Node *phead1, *phead2, *pold, *pafter, *pnext; phead1 = *pp1; phead2 = *pp2; pold = phead1 -> next; pafter = pold -> next; pnext = phead2; while(phead1 -> next){ if(n >= 3) { for(int i = 0; i < n - 2; i++) { pold = pold -> next; pafter = pold -> next; } } else if(n == 2) { pafter = pold -> next; } else if(n == 1) { pold = phead1; pafter = pold -> next; } //phead2未存储数据 if(!phead2 -> next) { phead2 -> next = pafter; pnext = pnext -> next; } //printf("pnext = %dn",pnext -> data); else { pnext -> next = pafter; pnext = pnext -> next; } pold -> next = pafter -> next; pold = pold -> next; //printf("pnext->next = %dn",pnext -> data); //printf("pold = %dn",pold -> data); //只剩下一个人n >= 2跳出循环的条件 if(pold == pold -> next) { pnext = pold; pnext -> next = NULL; break; } //n == 1跳出循环的条件 if(n == 1) { if(pafter -> next -> data == phead2 -> next -> data) { pafter -> next = NULL; break; } } } } //print void print(struct Node *p, int m) { for(int i = 0; i < m; i++) { printf("%4d",p -> next -> data); p = p -> next; } } void repeat(struct Node **pp) { struct Node *phead, *pnext; phead = *pp; pnext = phead -> next; while(pnext -> next) { pnext = pnext -> next; } pnext -> next = phead -> next; } //destroy void destroy(struct Node *p) { struct Node *pnext; while(p) { pnext = p -> next; free(p); p = pnext; } //printf("destroyed!"); } int main() { //新建两个链表的头节点 struct Node *phead1, *phead2; phead1 = createNew(); phead2 = createNew(); //输入人数 int m; scanf("%d",&m); //创建循环链表 build(&phead1,m); //第一次游戏 int x; scanf("%d",&x); append(&phead1,&phead2,x); //循环游戏 while(getchar() == ' ') { phead1 = phead2; repeat(&phead1); phead2 = createNew(); scanf("%d",&x); append(&phead1,&phead2,x); } //打印 print(phead2,m); //销毁 destroy(phead2); return 0; }



