一、题目链接
http://noi.openjudge.cn/ch0105/31/
二、解题思路
◎ 根据题目描述,可以确定如下事实:
→ 首先,1号灯始终是关闭的,因此可以先输出1;
→ 其次,对于其它灯而言,被第1个人操作后,初始状态是关闭的;
→ 然后,对于其它灯而言,将继续被其他若干人操作,此时灯的编号是操作人编号的整数倍;
→ 最后,对于其它灯而言,最终的状态取决于所有操作过它的人;
◎ 由于涉及取反操作,因此灯的状态用±1表示;
◎ 循环遍历除1号灯以外的其它灯,例如第i号灯:
→ 首先,标记第i号灯的初始状态是关闭的;
→ 其次,循环遍历除第1个人以外的其他人,例如第j个人:
*** 如果i是j的整数倍,说明第j个人可以操作第i号灯,此时对第i号灯的状态做取反操作;
→ 如果第i号灯最终为关闭状态,输出一个逗号和i。
三、实施步骤
◎ 首先,定义并输入两个int类型的整数N、M,分别代表灯的数量、人的数量;
◎ 其次,定义int类型的整数flag,代表灯的状态;
◎ 然后,输出1;
◎ 第四,通过标记i代表灯的编号,i从2开始,到N为止,更新步长为1,循环处理如下:
→ 令flag=-1;
→ 通过标记j代表人的编号,j从2开始,到M为止,更新步长为1,循环处理如下:
*** 如果i%j==0:令flag=-flag;
→ 如果flag==-1:输出一个逗号和i。
四、C++程序
#include <iostream>
using namespace std;
int main()
{
int N;
int M;
cin >> N;
cin >> M;
int flag;
cout << 1;
for (int i = 2; i <= N; i++)
{
flag = -1;
for (int j = 2; j <= M; j++)
{
if (i % j == 0)
{
flag = -flag;
}
}
if (flag == -1)
{
cout << "," << i;
}
}
return 0;
}