有 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;
}