【经典算法】开灯问题(Java)
题目描述:
有n盏灯,编号为1~n,第一个人把所有灯打开,第二个人按下所有编号为2的倍数开关(这些灯将被关掉),第三个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),一次类推,一共有k个人,问最后哪些灯开着?
输入:
3 7
输出 :
1 5 6 7
算法思想:
建立一个a数组,他的每个下标变量a[i]视为一盏灯,i表示其编号。a[i]=1表示第i盏灯处于打开状态;a[i]=0表示第i盏灯等处于关闭状态。
那么如何实现将第i盏灯做相反处理的开关灯操作呢?看这题的大部分都是新手,所以大部分第一时间就会想到if语句;当a[i]=0时a[i]=1,反之亦然。但是通过算术运算a[i]=1-a[i];会显得更好描述等的开关状态。我们把这种形式的赋值语句形象的成为"乒乓开关"。
代码如下:
public static void main(String[] args) {
//题目说明,若灯是亮的,则为1,否则为0
Scanner input = new Scanner(System.in);
int n =input.nextInt(); //有几个同学
int k=input.nextInt(); //有几盏灯
//灯是从第一盏开始,a[0]不管他,第一个人把每个灯都打开了,所以数组a的值都是1
int[] a = new int[100];
for (int i=0;i<=k;i++){
a[i]=1;
}
for (int i=2;i<=n;i++){ //n是人数
int p=1;
while(p*i<=k){ //判断i和的倍数 是否都小于灯的数量
a[p*i]=1-a[p*i]; //将等的状态置为相反
p++;
}
}
for(int i=1;i<=k;i++){
if (a[i]==1){
System.out.println("第"+i+"灯是亮的");
}
}
}
输出
第1灯是亮的
第5灯是亮的
第6灯是亮的
第7灯是亮的