版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/84441246
题目
描述 Description
n只猴子选大王,选举办法如下:从头到尾1,2,3,1,2,3……报数,凡报3的退出,余下猴子第二轮从尾到头1,2,3,1,2,3……报数,凡报3的退出...如此类推,当剩下两只猴子时,取这时报1的为王,若想当猴王,请问当初应占据什么位置?
输入格式 Input Format
一个数 n,表示n只猴子 n<=1000
输出格式 Output Format
一个整数,表示猴王的位置,也就是最后一个出队的猴子的位置。
样例输入 Sample Input
3
=下面为第二组====
7
样例输出 Sample Output
2
=下面为第二组====
2
时间限制 Time Limitation
1s
来源 Source
经典问题。数组基础练习题。
代码
(一般人的思维)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int monkey;//定义一个猴子变量,猴子变量最后变为2的时候,结束循环
int a[1000];//定义一个数组,主要是存放猴子,当猴子报数为3的时候,数组值置为0,最后统计数组值不为0的猴子,然后输出报数为1的猴子
int i;//定义循环变量
int count;//定义报数器,一旦报数器为3,就将数组中的值置为0,相当于淘汰猴子,然后将报数器重置为0;
int n;//输入猴子的数目,用于确定循环变量的边界
bool direction;// 定义一个布尔变量,方向,正向的话,从1到n,负向的话,从n到1,尤其是最后剩两个猴子的时候,要注意如何判别方向
cin>>n;
monkey=n;
for(i=1;i<=n;i++)//首先将数组中从1到n的数组值全都变成猴子的号码
{
a[i]=i;
}
while(monkey>2)
{
count=0;//计数器为0
direction=true;//从正向开始报数
for(i=1;i<=n;i++)
{
if(a[i]!=0) count=count+1;//如果数组中的值不为0,报数就加1,i和count同步,i是1,count是1. i是3的时候,count是3,不过一旦count是3,将a【3】中的值变成0,count重新变为0,i是4的时候,count是1了
if(count==3) //当报数变成3的时候,将对应的a[i]中的值置为0,然后将猴子的总数减去1;计数器置0.
{
a[i]=0;
monkey=monkey-1;
count=0;
}
}
if(monkey<3) break;//正向报数报完了一遍,开始查猴子数量,如果只有2只,就退出整个while的循环体,如果大于2只,开始进行负方向报数
count=0;//计数器置0
direction=false;//负方向开始进行报数,负方向报完,统计猴子数目,如果大于2,继续循环,从正方向报数,直到猴子数量是2.
for(i=n;i>=1;i--)
{
if(a[i]!=0) count=count+1;
if(count==3)
{
a[i]=0;
monkey=monkey-1;
count=0;
}
}
}
if(direction)//在猴子数量是2的时候,看布尔变量direction是正向还是负向,正向就从大到小报数,逆向就从小到大报数,是不是很意外,自己在纸上一画就知道了
{
for(i=n;i>=1;i--)
{
if(a[i]!=0)//return 0就表示只要输出一个,就退出循环体
{
cout<<a[i]<<endl;
return 0;
}
}
}
else
{
for(i=1;i<=n;i++)
{
if(a[i]!=0)
{
cout<<a[i]<<endl;
return 0;
}
}
}
return 0;
}
另一种方法(仅限大佬使用)
#include<bits/stdc++.h>
using namespace std;
int a[1100],n;
int main()
{
cin>>n;
for (int i=1;i<=n;i++)
a[i]=i;
while(n>=3)
{
for (int i=1;i<=n;i++)
if (i%3==0)
a[i]=0;
for (int i=1;i<=n;i++)
if (a[i]==0)
{
for (int j=i;j<n;j++)
a[j]=a[j+1];
n--;
}
for (int i=1;i<=n/2;i++)
swap(a[i],a[n-i+1]);
}
cout<<a[1]<<endl;
return 0;
}
下面是一个叫Joseph Circle的东西(其实本题就是这个约瑟夫环变形而来的)
#include<bits/stdc++.h>
using namespace std;
void monkeyKing(int m,int n)
{
int a[100];
int i,t,count;
for (i=0;i<m;i++) a[i]=1;
t=0;
printf("出列顺序:");
for (i=1; i<=m; i++)
{
count=1;
while(count<=n)
{
t=(t+1)%m;
if (a[t]==1) count=count+1;
}
a[t]=0;
printf("%d", t);
printf("\n");
}
}
int main()
{
int m,n;
printf("请输入猴子的个数和报数的数目");
scanf("%d %d",&m,&n);
monkeyKing(m,n);
return 0;
}