1. 程式人生 > >p1074 猴子選大王

p1074 猴子選大王

題目

描述 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;
 }