约瑟夫问题

1.

方法一:数组

#include<iostream>
#include<stack>
using namespace std;
#define N 10000
int num[N];
int main()
{
	int n,m,i,cnt=0;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		num[i]=i;
	int nt=n;
	i=1;
	while(n>1)
	{
		if(num[i]!=0) cnt++;
		if(cnt==m)
		{
			cout<<num[i]<<' ';
			num[i]=0;
			cnt=0;
			n--;
		}
		if(i==nt) i=1;
		else i++;
	}
	for(i=1;i<=nt;i++)
	{
		if(num[i]!=0) cout<<num[i];
	}
	return 0;
 }

方法二:队列

/*队列
q.push(item) //将item压入队列尾部
q.pop() //删除队首元素,但不返回
q.front() //返回队首元素,但不删除
q.back() //返回队尾元素,但不删除
q.size() //返回队列中元素的个数
q.empty() //检查队列是否为空,如果为空返回true,否则返回false 
*/
#include<iostream>
#include<queue>
using namespace std;
int main()
{
	int n,m,i,now=1;
	queue<int> q;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		q.push(i);
	while(!q.empty())
	{
		if(now==m)//如果报到第m个人
		{
			cout<<q.front()<<' ';
			q.pop();
			now=1;
		}
		else if(now!=m)//如果没有报到第m个人 
		{
			now++;
			q.push(q.front());//将队首元素压入队尾 
			q.pop();//删除队首元素 
		}
	}
	return 0;
}

对比后发现,队列的方法能大大简化代码,并且更好理解

2.

#include<stdio.h>
#define N 10000
int num[N];
int main()
{
	int n,m,i,count=0,nt;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
		num[i]=i;
	nt=n;
	i=1;
	while(n>1)
	{
		if(num[i]!=0) count++;
		//printf("count=%d\n",count);
		if(count==m)
		{
			num[i]=0;//报数为 m 的去掉 
			count=0;//printf("count=%d\n",count);
			n--;//圈里人数-1 
			//printf("n=%d\n",n);
		 } 
		 //printf("num[i]=%d\n",num[i]);
		 if(i==nt) i=1;
		 else i++;
		 //printf("i=%d\n",i);
	}
	for(i=1;i<=nt;i++)
	{
		if(num[i]!=0) printf("%d",num[i]);
	}
	return 0;
} 
posted @ 2020-04-16 22:52  jasf  阅读(172)  评论(0)    收藏  举报