约瑟夫问题
2012-03-27 16:30 璋廊 阅读(933) 评论(0) 编辑 收藏 举报Description
据传说,罗马人攻夺Jotapat后,Josephus和朋友两人与其他n个犹太人避难到一个洞穴里。使Josephus非常反感的是,他发现除了他自己和朋友外,其余的都决心殉难以免落入征服者的手中。他不敢太公然表示反对而只好同意了,但他坚持这一行动必须有条不紊地进行,并且建议大家坐成一圆圈,然后从洞口的人开始顺时针报数,数到m的人就杀掉,然后又从下一个人开始从1报数,直到最后一个人去自杀。问Josephus应该把自己和朋友放在第几个位置,才能避免被杀掉。注意:本题要求用链表实现。
Input
本题有多组测试数据,第一行是测试数据组数T,下面T行的每一行有两个用一个空格隔开的数n、m,表示犹太人数和报的数。其中1<=n<=99,1<=m<=999。
Output
输出共有T行,依次对应输入行。每行有两个数,从小到大排列,并用空格隔开。注意第二个数后没有空格。输出最后有一个空行。
Sample Input
1
2 2
Sample Output
1 3
Hint
位置是从洞口顺时针从1依次编号,报数也是从位置1的人顺时针报数。
/********************************* 建立循环链表,对于链表的删除和连接、: **********************************/ #include<stdio.h> #include<stdlib.h> typedef struct point//建立结构体指针 { int data; struct point *next; }Linkpoint,*LinkList; int x,y; LinkList built(int n)//建立循环链表: { int i; LinkList head,p,s; p=head=(LinkList)malloc(sizeof(Linkpoint)); head->data=1; for(i=2;i<=n+2;i++) { s=(LinkList)malloc(sizeof(Linkpoint)); s->data=i; p->next=s; p=s; } p->next=head; return head; } void count(LinkList head,int m)//寻找地m个猴子,踢出去; { int i=1; LinkList p,q; p=head; while(p->next!=p) { if(i==m-1) { q=p->next;//连接链表; p->next=q->next; x=q->data; free(q); i=1; p=p->next; } else { p=p->next; i++; } } y=p->data; } int main() { int n,m,t; LinkList head; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); if(m==1) { printf("%d %d\n",n+1,n+2); } else { head=built(n); count(head,m); if(x>y) printf("%d %d\n",y,x); else printf("%d %d\n",x,y); } } return 0; }