您的位置:首页 > 编程语言 > C语言/C++

C++经典题目:约瑟夫环问题

2013-09-26 23:48 274 查看

问题描述:

有n个人围成一圈,顺序排号。从第一个人开始报数(1~3报数),凡报到3的人退出圈子,问最后留下的人原来排在第几号。

分析:

首先由用户输入人数n,然后对这n个人进行编号【因为如果不编号的话,我们就不能知道最后是哪位童鞋留下来了:)】

然后就开始了一圈一圈的循环,不断形成新的圈子,不断有人被淘汰,那么循环到什么时候截止呢?对只剩最后一个人,也就是说淘汰n-1了个人的时候,这个时候停止循环。

在实际情况中,应该是这n个人一开始围成了一个大圈子,然后随着不断的淘汰,圈子不断减小,最后剩下的那个人的一开始的编号就是我们要的结果。

我在用数组来表示这些人,因为进行了初始化,所以数组中元素的值都是原来的编号,因此我们只需要将被淘汰的人对应的数组元素的值设置为0即可。然后随着不断的循环,最后只剩下一个值不为0的数组元素,这个元素就是我们要的结果。

程序代码

#include<iostream>
using namespace std;
int main()
{
int i;			//i用来记录数的那个数字
int k,j;		//k用来记录淘汰的人数 ,j用来表示第j个人
int Array[10];
//对10个人进行编号
for(i=0;i<10;i++)
{
Array[i]=i+1;
}
i=1;
k=0;
/*因为n个人围成一个圈,所以当j>n的时候,j要除n取余,例如(n+1)%n=1
之所以要++j,而不是j++是因为要先加1再判断*/
for(j=0;k<9;j=++j%10)
{
if(Array[j]!=0)//当j对应的人没有被淘汰时参与进来,淘汰的直接忽略
{
if(i==3)		//当j对应的人数到m的时候
{
k++;		//淘汰人数加1
Array[j]=0;	//对应数组中的数据置为0
i=1;		//重新开始报数
}
else
{
i++;		//当j对应的人数没有数到m,则进行下一个
}
}
}
for(i=0;i<10;i++)
{
if(Array[i]!=0)//通过上面的操作,所有淘汰的人员数组对应的值都为0,不为0的就是留下来的
{
cout<<"留下来的是,第"<<i+1<<"个人"<<endl;
}
}
cout<<endl;
return 0;
}


一些扩展

我们可以对上述程序做一些扩展,让用户输入总人数和用于淘汰的那个数字。

#include<iostream>
using namespace std;
int main()
{
int i;			//i用来记录数的那个数字
int n,m;
int k,j;		//k用来记录淘汰的人数 ,j用来表示第j个人
cout<<"请输入总人数n和用于淘汰的数字m:";
cin>>n>>m;
int *Array=new int
;
//对n个人进行编号
for(i=0;i<n;i++)
{
Array[i]=i+1;
}
i=1;
k=0;
/*因为n个人围成一个圈,所以当j>n的时候,j要除n取余,例如(n+1)%n=1
之所以要++j,而不是j++是因为要先加1再判断*/
for(j=0;k<n-1;j=++j%n)
{
if(Array[j]!=0)//当j对应的人没有被淘汰时参与进来,淘汰的直接忽略
{
if(i==m)		//当j对应的人数到m的时候
{
k++;		//淘汰人数加1
Array[j]=0;	//对应数组中的数据置为0
i=1;		//重新开始报数
}
else
{
i++;		//当j对应的人数没有数到m,则进行下一个
}
}
}
for(i=0;i<n;i++)
{
if(Array[i]!=0)//通过上面的操作,所有淘汰的人员数组对应的值都为0,不为0的就是留下来的
{
cout<<"留下来的是,第"<<i+1<<"个人"<<endl;
}
}
cout<<endl;
return 0;
}

11计信班赵哲
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: