STL关于约瑟夫环问题

STL关于约瑟夫环问题,第1张

关于约瑟夫环的改编问题是这样的:假设有 N 个人,围成一圈,然后给你一个数 M ,围成一圈的人当中一个从 1 开始数,然后数到 M 退出,接下来剩下来的人继续从 1 开始继续数, 直到剩下最后一个人,求剩下这个人刚开始的位置。


刚开始学习 C语言的时候接触这个问题,对于不爱动脑的我,是非常难的,所以我去向学长请教,然后学长跟我说了 “环形数组”,真是醍醐灌顶 (hhhh...)然后我就抱着试一试的心态去写代码了,刚开始的代码如下:

#include
int arry[1010], sum = 0, N, M;

int main()
{	
	scanf("%d %d",&N, &M);
	for(int i=1,cnt=0;i<=N;i++)
	{	
		if(arry[i]==0 && sum < N - 1)
		{
			cnt++;
			if(cnt==M)
			{	
				arry[i]++;
				sum++;
				cnt=0;
			}
		}
		if(i == N) i=0;
		if(sum == N-1) break;
	}
	for(int i=1;i<=N;i++)
	{
		if(arry[i]==0) printf("%d\n",i);
	}
	return 0;
}

思路也比较简单,就是刚开始把每个数组上面的数全部置 0 ,数到的就自增 1 就认为退出了,然后不断进行遍历到 N - 1 个数就行了。


当然这篇文章并不是讲 C 语言的, 其当中的思想就是一个环形数组,对于环形数组来说,在 C++ 的 STL 里面有一个数据结构 "queue".这个数据结构叫做栈,因为和环形数组很像,所以就想到这个问题,先上代码:

#include
#include
using namespace std;

int n, m, temp;

queue  lis;

int main()
{
	cin >> n >> m;
	for(int i = 1; i <= n ; i++)
	{
		lis.push(i);
	}
	int cnt = 1;
	while(!lis.empty())
	{
		temp = lis.front();
		lis.pop(); 
		if(cnt == m) 
		{
			cnt = 0;
		}
		else
		{
			lis.push(temp); 
		}
		cnt++;
	}
	cout << temp<

这样就不用那么复杂了,这就相当于一个队伍,数到不是 M 的就从队首离开,然后到队尾继续排队。


文章如有错误,请dalao批评改正。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/569824.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)