约瑟夫环问题(C++)(非递归)

简便的方法解决约瑟夫环问题

之前遇到过很多次约瑟夫环的题,一直是在用递归的方法解决,但每次考虑递归的时候都会考虑到发狂,最后终于总结出了一个较为简单的方法

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

一开始在编程的时候会有一个惯性思维就是所谓的“退出圈外”,最常想到的就是把这个数从数组中删除,但这样做不仅麻烦并且计算量很大,而换一种思维,就是将退出圈外变为跳过这个数直接记录下一个数。

废话不多说,直接贴代码

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {
	int n,m;
	cin>>n>>m;
	while(n!=0&&m!=0)
	{
		int a[n];
		for(int i=0;i<n;i++)
		{
		    a[i]=0;     //先将数值中的数值全部置零
		}
		int index=-1;      //这里要用负一,否则下面就从一开始了
		int count;      //定义一个计数器
		for(int i=1;i<n;i++)
		{
			count=0;
			while(m!=count)       //当计数器数到m时退出循环进行归零
			{
				index=(index+1)%n;
				if(a[index]==0)
				{
					count++;     //如果是零计数器加一,如果是一计数器不计入
					if(count==m)
				    {
					    a[index]=1;     //让第m个数变为一
				    }
				}
			}
		}
		for(int i=0;i<n;i++)
		{
			if(a[i]==0)
			{
				cout<<i+1<<endl;
			}
		}
		cin>>n>>m;
	}
	return 0;
}

总的来说就是保持数组不变,仅仅是跳过不要的数而不是删去,这样可以节约很多资源

当然,这只是我这个菜鸟的一点总结,高手直接略过好了…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值