956: 约瑟夫问题的实现
循环链表
题目描述
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<iostream>
#include<malloc.h>
using namespace std;
typedef struct link
{
int data;
link *next;
}linklist;
linklist* store(linklist *&p1,int n)
{
p1=(linklist *)malloc(sizeof(linklist));
p1->next=NULL;
p1->data=1;
linklist *l1,*l2;
l1=p1;
for(int i=2;i<=n;i++)
{
l2=(linklist *)malloc(sizeof(linklist));
l2->data=i;
l1->next=l2;
l1=l2;
}
l1->next=p1; //让尾结点和头结点链接
return l1; //返回尾结点
}
void win(linklist *&p1,linklist *&p2,int k,int n)
{
linklist *l2;
int i=0; //记录报数
int num=0; //记录已报数的人数
l2=p2; //同步指针
while(p1!=NULL)
{
i++;
if(i==k)
{
i=0;
num++;
l2->next=p1->next;
p1=l2->next;
}
else
{
p1=p1->next;
l2=l2->next;
}
if(num==n) break; //报到最后一人退出循环
}
}
void Cout(linklist *p1)
{
cout << p1->data;
}
void Free(linklist *&p1,linklist *&p2)
{
linklist *l,*s;
l=p1;
s=p1->next;
while(s!=NULL)
{
free(l);
l=s;
s=l->next;
}
free(l);
}
int main()
{
int n,k;
cin >> n >> k;
linklist *p1,*p2;
p2=store(p1,n);
win(p1,p2,k,n);
Cout(p1);
return 0;
}