一、题目链接
http://noi.openjudge.cn/ch0105/31/
二、解题思路
◎ 根据题目描述,可以确定如下事实:
→ 1号灯从头至尾肯定是关闭的,由此可以先输出1;
→ 对于所有i号灯(不含1号灯)而言,被第1个人操作后,其初始状态肯定是关闭的;
→ 对于所有i号灯(不含1号灯)而言,被第1个人操作后,将继续被第2至第m个人中的若干人操作,此时需要满足条件i % j == 0,这里j
代表第2至第m个人中某个人的编号;
→ 对于所有i号灯(不含1号灯)而言,最终的状态取决于第2至第m个人中所有操作过它的人;
◎ 定义并输入两个int类型的整数N、M,分别代表灯的数量、人的数量;
◎ 定义int类型的整数flag,代表当前灯的状态,由于涉及取反操作,因此flag取值为±1;
◎ 1号灯肯定是关闭的,由此先输出1;
◎ 从2号灯开始,到N号灯为止,利用循环i处理如下:
→ 首先,令flag = -1,也即标记当前i号灯的初始状态是关闭的;
→ 其次,从第2个人开始,到第M个人为止,利用循环j处理如下:
*** 如果i % j == 0,代表第j个人可以操作当前i号灯,令flag = -flag,也即做取反处理;
→ 循环j结束后,如果flag等于-1,代表当前i号灯最终为关闭状态,输出一个逗号和i;
循环i结束后,所有最终状态为关闭的灯号均被输出。
三、Java程序
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int N = input.nextInt();
int M = input.nextInt();
int flag;
System.out.print(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) {
System.out.print("," + 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;
}