ACM学习历程16——List链表的应用之简单约瑟夫问题

约瑟夫问题是list链表的应用之一,问题描述:N个人围成一个圆圈,每个人都有唯一的一个编号,编号从1到N,从编号为1的人开始报数,依次报到K,报数为K的人出列,他的下一个又从1开始报数,直到所有的人都出列,求这个出列的序列。结合上一篇博客,这里使用list链表,给出一个可行的解答代码。

注:n为人数,p为要报的数。

#include
#include

using namespace std;

int main()
{
	int n,p;
	list l;

	while(cin>>n>>p)
	{
		l.clear();
		for(int i=1;i<=n;i++)
		{
			l.push_back(i);
		}

		list::iterator it,pdel;

		it=l.begin();
		while(l.size()!=1)
		{
			//报数,it指向要删除的元素
			for(i=1;i";
			pdel=it;

			it++;
			it= (it==l.end()) ? l.begin() : it;

			l.erase(pdel);
		}
		cout<<*it<
ACM学习历程16——List链表的应用之简单约瑟夫问题_第1张图片

Java版本的简单约瑟夫环:

public class test 
{
	public static void main(String[] args) 
	{
		CycLink cyclink=new CycLink();
		cyclink.setLength(5);
		cyclink.createLink();
		cyclink.printLink();
		cyclink.setK(2);
		cyclink.setM(2);
		cyclink.play();
	}
}

class Child
{
	int number;
	Child nextChild;
	public Child(int number)
	{
		this.number=number;
	}
}

//环形链表
class CycLink
{
	//环形链表大小
	//指向第一个小孩的应用不能动
	int length=0;
	int k=0;
	int m=0;
	Child firstChild=null;
	Child temp=null;
	//设置链表大小
	public void setLength(int length)
	{
		this.length=length;
	}
	
	public void setK(int k)
	{
		this.k=k;
	}
	
	public void setM(int m)
	{
		this.m=m;
	}
	//初始化环形链表
	public void createLink()
	{
		for(int i=1;i<=length;i++)
		{
			//创建第一个小孩
			if(i==1)
			{
			   Child child=new Child(i);
			   this.firstChild=child;
			   this.temp=child;
			}
			else
			{
				Child child=new Child(i);
				this.temp.nextChild=child;
				this.temp=child;
				if(i==this.length)
				{
					//创建最后一个小孩
					this.temp.nextChild=this.firstChild;
				}
			}
		}
	}
    public void printLink()
    {
    	Child temp=this.firstChild;
    	do
    	{
    		System.out.print(temp.number+" ");
    		temp=temp.nextChild;
    	}while(temp!=firstChild);
    	System.out.println();
    }
    
    public void play()
    {
    	Child temp=this.firstChild;
    	//找到数数的结点
    	for(int i=1;i
约瑟夫问题还有其它变形,如从第M个开始报数或者当某个人出队后重新给定下一次报数的值等,只需要在第一个C++程序的基础上做修改即可。

你可能感兴趣的:(ACM心路)