p1074 猴子选大王

版权声明: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;
 }

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/84441246