约瑟夫环 (c++循环链表方法书写)

748:约瑟夫问题

问题描述

约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入

每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:0 0

输出

对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号

样例输入

6 2
12 4
8 3
0 0

样例输出

5
1
7
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
//所用的全部函数
listnode createlist(int n);
int 	run(int n,int m);
int 	cinn();

typedef struct node
{
	int number;
	struct node *next;
}node,*listnode;

int main()
{
	int i=0,x[3000];	//由于要保证一直输入,所以我们以数组X来存放约瑟夫环的值
	while(1)		//保证以至能输入
	{
		x[i]=cinn();
		if(x[i]==0)		//当输入0 0时跳出输入循环,即输入截至
		{
			break;
		}
		i++;
	}
	for(int j=0;j<i;j++)//输出值
	{
		cout<<x[j]<<endl;
	}
	return 0;
}

listnode createlist(int n)	//很简单的创建单链表,在这里我们没有直接创建为循环链表,因为当m=1时单链表更好操作
{
	int number=1;
	node*pre,*curr;
	listnode l=new node;
	l->next=NULL;
	l->number=number;
	pre=l;
	while(--n)
	{
		curr=new node;
		curr->number=++number;
		pre->next=curr;
		curr->nexy=NULL;
		pre=curr;
	}
	return l;
}

int run (int n,int m)
{
	listnode l=createlist(n);
	listnode x=1;
	node*pre=NULL;
	int number=1,temp=0;
	if(m==1)
	{
		while(l->next!=null)	//当m=1时单独处理
		{
			l=l->next;
		}
		temp=l->next;
	}
	else	//这里就是当m!=1时,讲单链表变为循环链表
	{
		while(l->next!=NULL)
		{
			l=l->next;
		}
		l->next=x;	//变换成功
		while(x->next!=x)	//约瑟夫环运行主要操作
		{
			for(int i=0;i<m-1;i++)	//重点:是m-1
			{
				pre=x;
				x=x->next;
			}
			pre->next=x->next;
			x=pre->next;
		}
		temp=x->number;
	}
	return temp;
}

int cinn()
{
	int n,m,x;
	cin>>n>>m;
	if(n==0&&m==0)
	{
		return 0;
	}
	else
	{
		x=run(n,m);
		return x;
	}
}

看完记得点个赞再走哦~拜托啦。

原文地址:https://www.cnblogs.com/Kuller-Yan/p/12914128.html