简单双向链表的实现&新约瑟夫问题

题目描述:

给定m个人,从s开始报数,数字顺加,报到n的人出列,然后数字顺减报到k的人出列,求出列顺序

样例输入:


8 1 3 2

样例输出:

3 6 1 5 2 8 4 7

分析:

约瑟夫问题主要就是处理边界,因此选用链表,第一个指向最后一个,最后一个指向第一个。

注意,这里链表不用指针!不用指针!为什么?因为m<=100,链表节点数量小,可直接用数组+结构体!

 q为前驱,h为后继。

完整代码如下:

#include <iostream>
#include <map>
#include <cstdio>

using namespace std;
int m,s,n,k,cnt,pd=true,pd2=true;
struct lb
{
	int q,h;
}a[105];

void del(int x)//删除节点
{
	a[a[x].q].h=a[x].h;
	a[a[x].h].q=a[x].q;
}

int main()
{
//	freopen("newjsf.in","r",stdin); //打开输入文件
//	freopen("newjsf.out","w",stdout); //打开输出文件
	
	cin>>m>>s>>n>>k;
	a[1].q=m,a[1].h=2,a[m].q=m-1,a[m].h=1;
	cnt=m;
	for(int i=2;i<=m-1;i++)
	{
		a[i].q=i-1,a[i].h=i+1;
	}
	while(cnt>0)
	{
		if(pd)
			for(int i=1;i<=n;i++)
			{
				if(pd2)//判断是否第一个人
				{
					pd2=false;
					continue;
				}
				s=a[s].h;
			}
		else
			for(int i=1;i<=k;i++) s=a[s].q;
		cout<<s<<" ";
		cnt--;
		del(s);
	} 
		
	fclose(stdin);//关闭输入文件
	fclose(stdout);//关闭输出文件
} 

  

原文地址:https://www.cnblogs.com/huaruoji/p/11729389.html