约瑟夫问题
2012-03-27 16:30 璋廊 阅读(946) 评论(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;
}
浙公网安备 33010602011771号