约瑟夫环的三种解法

约瑟夫环的三种解法

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。
N个人从1开始编号,问最后活下来的人的编号是多少。

方法1:数组模拟。

#include<bits/stdc++.h>
using namespace std;
int main(){
	 printf("--------约瑟夫环问题----------\n");
	 printf("请输入总共人数和报数死亡的编号数:");
	 int n,m;
	 cin>>n>>m;
	 bool a[n+1];
	 memset(a,0,sizeof(a));
	 int tot=0,cnt=0,i=0;//当前死亡总人数,报数的报数器.
	 while(cnt<n){
	 	i++;
	 	if(i>n) i=1;
	 	if(!a[i]) cnt++;
	 	if(cnt==m){
	 		cnt=0;
	 		tot++;
	 		a[i]=1;
	 		printf("第%d个死的人的编号为%d\n",tot,i);
		 }
	 }
	 printf("游戏结束,所有人死亡\n");
	 return 0;
} 

方法2:数学递推

主要是利用递推的思想,令Y[ i ]为有i个人时最后活着的人的编号(从0开始编号)。显然Y[ 1 ]=0,现在我们来考虑Y[2]为多少。我们已知报到 m-1 的会死.
所有当有两个人的时候.死的就是那个报m-1的人.然后编号为m的那个人就活了下来.所以Y[ 2 ] = Y[ 1 ] + m
依次进行递推:可得Y[ i ] = Y[ i-1] + m ,由于我们知道报数类似于一个循环.所以编号可能会超出范围.所以我们对每一个进行取模。 Y[ i ] = ( Y [ i- 1] + m) % i ,对 i 取模 保证 编号是从0到 i -1 。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m;
	while(cin>>n>>m){
		int p=0;
		for(int i=2;i<=n;i++){
			p=(p+m)%i;// i=2时是n=2时最后活着的人编号(从0开始),i=1时,最后活着的人编号肯定为0 
		}
		printf("最后活着的人的编号为%d\n",p+1);
	}
} 

方法3:队列实现.

将队伍看成一个循环队列.如果没点到第m个人就放到队尾,否则弹出,cnt重置.下面上代码.

#include<bits/stdc++.h>
using namespace std;
int main(){
	queue<int>q;
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) q.push(i);
	int cnt=1;
	while(q.size())
	{
		if(cnt==m)
		{
			printf(q.size()==1?"%d\n":"%d ",q.front());
			q.pop();
			cnt=1;
		}
		else {
				int tmp=q.front();
				cnt++;
				q.pop();
				q.push(tmp);
		 }
	}
	return 0;
}
全部评论

相关推荐

感觉这一周太梦幻了,就像一个梦,很不真实~~~感觉这个暑期,我的运气占了99成,实力只有百分之一4.15上午&nbsp;腾讯csig&nbsp;腾讯云部门,面完秒进入复试状态4.16下午&nbsp;美团优选供应链部门,4.18上午发二面4.17晚上&nbsp;阿里国际一面,纯拷打,面完我都玉玉了4.18下午&nbsp;阿里国际二面,是我们leader面的我,很轻松~~4.18晚上&nbsp;约了hr面4.19上午&nbsp;hr面,下午两点口头oc4.19晚上&nbsp;意向书说起来我的暑期好像一次都没挂过~~~~~难道我是天生面试圣体?----------------------------------------------------------------------六个月前,我还是0项目0刷题,当时想的是先把论文发出来再去找实习。结果一次组会,老师打破了我的幻想(不让投B会,只让投刊或者A)我拿头投啊!!!然后就开始物色着找实习,顺便做完了mit的6.s081,但是基本上还是没刷过题目-----------------------------------------------------------------------11月&nbsp;&nbsp;一次偶然的机会,面进了某个耳机厂的手环部门,大概是做嵌入式的,用的是CPP。12月&nbsp;莫名其妙拿到了国创的面试机会,0基础四天速成java基础!居然也给我面过了hhhhh,可能是面试没写题吧入职国创后的几个月,一直没活,天天搁那看剧,都快忘了还有暑期实习这回事了~~~~命运的齿轮在2.26开始转动,因为这一天美团开了,我开始慌了,因为那时的我什么都不会。lc,八股,sql全部是0进度。然后就开始了女娲补天,上班刷题,下班继续做之前的开源,顺便学一学八股。3月到现在,lc也刷到快200了,一天最多提交了47次~~~~~~~~~~八股根据别人的面经总结和博客,写了快十万字的笔记~~~~~~~~~~简历上的实习经历和开源,也努力去深挖了,写了几万字的记录~~~~~~所以面试的时候,基本上都能cover了,面试官问到的基础基本都会,不基础的我就把他往我会的地方引。结果好像还不错,基本上每个面试官评价都挺好的emmmmmmmm
投递阿里巴巴等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务