约瑟夫问题的实现
n个人围成一个圈,每个人分别标注为1、2、...、n,要求从1号从1开始报数,报到k的人出圈,接着下一个人又从1开始报数,如此循环,直到只剩最后一个人时,该人即为胜利者。例如当n=10,k=4时,依次出列的人分别为4、8、2、7、3、10,9、1、6、5,则5号位置的人为胜利者。给定n个人,请你编程计算出最后胜利者标号数。(要求用单循环链表完成。)
输入
第一行为人数n;
第二行为报数k。
输出
输出最后胜利者的标号数。
样例输入
10
4
样例输出
5
#include<stdio.h>
#include<malloc.h>
struct LinkNode
{
int data;
struct LinkNode *next;
};
int main()
{
int n,k;
struct LinkNode *head,*p1,*p2,*p;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
{
if(i==1)//创建头结点
{
head=p1=p2=(struct LinkNode*)malloc(sizeof(struct LinkNode));
}
p1->data=i;//储存数据
if(i<n)
{
p2=(struct LinkNode*)malloc(sizeof(struct LinkNode));
p1->next=p2;
p1=p2;
}
if(i==n)//设置最后一个结点的next为头结点,这样就是一个循环链表
{
p1->next=head;
}
}
p=head;
int t=0;
for(int i=1; ; )
{
if(i%k==0&&p->data!=0)//模拟报数 1%k= ,表示轮到此结点报数,p->data!=0,表示 此结点未报过数
{
if(t<n-1)
{
p->data=0;//这个结点已经报过数,标识为0
t++;
i++;
}
else
{
printf("%d",p->data);
break;
}
}
else if(p->data!=0)
{
i++;
}
p=p->next;
}
}
/*
#include<stdio.h>
int main()
{
int n,k;
int a[1000]={0};
int t=0;
scanf("%d %d",&n,&k);
int j=0;
for(int i=n;i>1; )
{
for( ; ;j++)
{
j=j%n;
if(a[j]==0)
t++;
t=t%k;
if(t==0&&a[j]!=1)
{
a[j]=1;
i--;
}
if(i==1)
break;
}
}
for(int i=0;i<n;i++)
if(a[i]==0)
printf("%d",i+1);
}
*/