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

JZYZOJ 猴子選大王

一道卡了我很久的水題

引入 約瑟夫環

題目背景
約瑟夫是一個無聊的人!!!

題目描述
n個人(n<=100)圍成一圈,從第一個人開始報數,數到m的人出列,再由下一個人重新從1開始報數,數到m的人再出圈,……依次類推,直到所有的人都出圈,請輸出依次出圈人的編號.

輸入輸出格式
輸入格式:
n m

輸出格式:
出圈的編號

輸入樣例#1:
10 3
輸出樣例#1:
3 6 9 2 7 1 8 5 10 4

簡單的模擬

#include <bits/stdc++.h>

using namespace std;

inline int read()
{
	int s = 0, w = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9')
	{
		if(ch == '-') w = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9')
	{
		s = (s << 1) + (s << 3) + ch - '0';
		ch = getchar();
	}
	return s * w;
}

#define MAXX 110

int n, m;
int a[MAXX];
int ans = 0;
int all;

int main()
{
	memset(a, 0, sizeof(a));
	n = read();
	m = read();
	all = n;
	for(int i = 1; i <= n; ++i)
	{
		if(a[i] != 1) ans++;
		if(ans == m)
		{
			a[i] = 1;
			printf("%d ", i);
			all--;
			ans = 0; 
		}
		if(i == n && all >= 1)
		{
			i = 0;
		}
	}
	return 0;
}

猴子選大王

還是簡單的模擬(只不過比約瑟夫複雜了一點)

#include <bits/stdc++.h>

using namespace std;

inline int read() {
	int s = 0, w = 1;
	char ch = getchar();
	while(!isdigit(ch)) { if(ch == '-') w = -1; ch = getchar(); }
	while(isdigit(ch)) { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar();}
	return s * w;
}

#define MAXX 1100

int n, x;
int a[MAXX]; 
int k, kk;

int main() {
	k = 1;
	n = read(); x = n;
	memset(a, 0, sizeof(a));
	int ans = 1;
	for(int i = 1; i <= n; ++i) {
		if(ans == 4) ans = 1;
		a[i] = ans;
		++ans;
	}
	while(x > 2) {
		for(int i = 1; i <= n; ++i) {
			if(a[i]) {
				if(a[i] == 3) {
					a[i] = 0;
					x--;
				}
			}
		}
		if(k) {
			k = 0; kk = 1;
			int ans = 1;
			for(int i = n; i >= 1; --i) {
				if(ans == 4) ans = 1;
				if(a[i]) {
					a[i] = ans;
					++ans;
				}
			}
		}
		else {
			if(kk) {
				k = 1; kk = 0;
				int ans = 1;
				for(int i = 1; i <= n; ++i) {
					if(ans == 4) ans = 1;
					if(a[i]) {
						a[i] = ans;
						ans++;
					}
				}
			}
		}
	}
	for(int i = 1; i <= n; ++i) {
		if(a[i] == 1) printf("%d", i);
	}
	return 0;
}