約瑟夫環(陣列實現)

Kirito_w發表於2020-12-14

有 m 個人, 每次數 n 個殺死,問從第幾個開始數可以保證第一個人活到最後。

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define endl '\n'
using namespace std;

const int N = 1e6 + 100;

int a[N];
int n, m;


bool solve(int x)
{
	int head = x - 1;   // 因為數的時候要記第一個人,所以從第一個人的前一個開始。
	for(int i = 0; i < m; i ++)    //m個回合,每回合殺一個人
	{
		int j = 0;
		while(j < n)     //數n個活著的人
		{
			head = (head + 1) % m;  //每次向後移一位並對總人數取模,保證head在【0,m - 1】區間內。

			if(a[head] == 0) j ++;  //標記為0說明這個人還活著,可以進入計數。
		}
		a[head] = 1;  //標記為1說明這個人已經被殺了
		if(i == m - 1) break;  //如果到了最後一個回合活著的人是隊長的話就跳出,返回真
		if(head == 0) return false;  //如果在某個回合隊長被殺了就結束遊戲,返回假
	}
	return true;
}

void init()
{
	memset(a, 0, sizeof a); //對陣列a進行初始化
}

int main()
{
	cin >> m >> n;
	if(m == 1) cout << "impossible" << endl;   //m為1的時候不管怎麼殺都會死
	else
	{
		for(int i = 0; i < m; i ++) 	//從第一個人開始列舉到從最後一個人開始,判斷哪種情況滿足隊長不死
		{
			init();
			if(solve(i))  //如果從第i個人開始隊長不死的話,直接輸出這個人,並跳出迴圈
			{
				cout << i + 1;  //陣列從零開始使用,所以編號需要 +1.
				break;
			}
		}
	}
	return 0;
}

相關文章