设置一个while(1)循环,把起始报的数字设为p。设置一个live数组,表示所有人存活情况。
再设一个while(1)循环,首先判断如果人在的话,报的数+1;但如果报的数和7有关,就淘汰。判断蔡佬是否被淘汰,如果被淘汰,就统计在场存活的人数,如果全场都被淘汰了,表明蔡佬是最后一个被淘汰的,p是可以的,做个标记,跳出第二个while循环;如果不可以,表明这个p不行,也要退出第二个循环了。(第二个循环其实就是判断当前这个p行不行,不行就跳出循环换一个)
回到第一个while循环。如果p可以(刚刚做标记了),就输出p,跳出第一个循环去下一个案例。如果p不行,p++,从头再试一遍。
文字写的不太清楚,可以搭配注释看代码之后,自己复现一遍。注释写的够清楚了。
#include<iostream>
using namespace std;
bool f(int m)
{
if (m % 7 == 0)
{
return true;
}
while (m > 0)
{
if (m % 10 == 7)
{
return true;
}
m /= 10;
}
return false;
}
int main()
{
int n;
cin >> n;
while (n--)
{
int m, p = 1, student = 0;//p从1开始,student从0号开始
cin >> m;
while (1)
{
bool* live = new bool[m]();//live数组,记录每个人的存活情况,为了省事,初始化为0。0代表存活,1代表死了
bool isBreak = false;
int number = p;//报数,从p开始
while (1)
{
int cnt = 0;//计数器,计数存活人数
if (live[student % m] == 0)//student%m代表0~m-1号学生,0表示存活
{
if (f(number))live[student % m] = 1;//f函数判断当前报数与7是否有关,如果有关,那么把该名学生记为1
number++;//继续报数
}
if (live[0] == 1)//0号是蔡佬,当蔡佬被淘汰时,统计全场淘汰人数
{
for (int j = 0; j < m; j++)//统计全场淘汰人数
{
if (live[j] == 0)cnt++;
}
if (cnt == 0)isBreak = true;//如果全场都被淘汰,表明蔡佬是最后被淘汰的,这个p可以,就可以跳出这个循环啦!如果不是,就表明这个p不可以,改换一个p啦!
break;//直接跳出循环
}
student++;//下一个学生
}
if (isBreak)//如果p可以就输出p
{
cout << p << "\n";
break;//换下一个案例
}
else p++;//p不可以,换一个p吧~
}
}
return 0;
}