2746:约瑟夫问题
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。
输入
-
每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:
0 0
输出
-
对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号
样例输入
-
6 2 12 4 8 3 0 0
样例输出
-
5 1 7
-
解析:
-
1:利用循环链表存储1....n的数字
-
2:通过n-1次循环逐个释放相关结点
-
3:关键:每次释放一个结点后p,q指针都要再次指向下一个相同结点
-
源代码如下:
-
#include<stdio.h> #include<stdlib.h> typedef struct Node{ int e; struct Node *next; }Node,*DLB; void Init(DLB &List){ List=(DLB)malloc(sizeof(Node)); List->next=List; } void Input(DLB &List,int n){ int i; Node *p,*q; q=List; for(i=1;i<=n;i++) { if(i==1) { List->e=i; } else { p=(DLB)malloc(sizeof(List)); p->e=i; p->next=q->next; q->next=p; q=q->next; } }//for }//Input int Slve(DLB &List,int n,int m){ int i,j; Node *p,*q; p=List; q=List; for(i=1;i<=n-1;i++) { for(j=2;j<=m;j++) { p=p->next; if(j<m)q=q->next; } q->next=p->next; free(p); p=q->next; q=q->next; }//for return q->e; } int main() { int n,m; while(scanf("%d %d",&n,&m)&&(n!=0||m!=0)){ DLB List; int i; Init(List);//初始化循环链表 Input(List,n);//存储1...n数字 printf("%d\n",Slve(List,n,m)); }//while //system("pause"); return 0; }
-