前言
这里有 100 张写着数字 1~100 的牌,并按顺序排列着。最开始所有牌都是背面朝上放置。某人从第 2 张牌开始,隔 1 张牌翻牌。然后第 2,4, 6, …, 100 张牌就会变成正面朝上。接下来,另一个人从第 3 张牌开始,隔 2 张牌翻牌(原本背面朝上的,翻转成正面朝上;原本正面朝上的,翻转成背面上)。再接下来,又有一个人从第 4 张牌开始,隔 3 张牌翻牌( 图1 )。像这样,从第 n 张牌开始,每隔 n-1 张牌翻牌,直到没有可翻动的牌为止。
问题
求当所有牌不再变动时,所有背面朝上的牌的数字。
代码
public class Q03 {
public static void main(String[] args) {
//0位置不用
int[] data = new int[101];
// method1(data);
method2();
}
private static void method2() {
// i 1 - 100 位置被翻的所有可能,考虑的是每牌的被翻
for (int i = 1; i < 101; i++) {
boolean flag = false;
//j=1一次不算,表示没有翻。
//已经翻转过的部分不再翻转 1%1(符合) 2%1 2%2 3%1 3%3 4%1 4%2 4%4(符合).....
for (int j = 1; j < 101; j++) {
if (i%j == 0) {
flag = !flag;
}
}
if (flag) {
System.out.println(i);
}
}
}
private static void method1(int[] data) {
for (int i = 0; i < data.length; i++) {
data[i] = 0;
}
for (int i = 2; i < data.length; i++) {
int j = i;
while(j < data.length) {
data[j] = data[j] == 0 ?1:0; //data[] 类型为int
// data[j] = !data[j]; //data[] 类型为false
j +=i;
}
}
for (int i = 0; i < data.length; i++) {
if (data[i] == 0) {
System.out.println(i);
}
}
}
}
答案
1、4、9、16、25、36、49、64、81、100
思路改进
method2() 是用数组来实现的,但从左到右按顺序处理也就意
味着“已经翻转过的部分不再翻转”。如果针对这一点进行优化,还可
以继续简化程序,如method2();
private static void method2() {
// i 1 - 100 位置被翻的所有可能,考虑的是每牌的被翻
for (int i = 1; i < 101; i++) {
boolean flag = false;
//j=1一次不算,表示没有翻。
//已经翻转过的部分不再翻转 1%1(符合) 2%1 2%2 3%1 3%3 4%1 4%2 4%4(符合).....
for (int j = 1; j < 101; j++) {
if (i%j == 0) {
flag = !flag;
}
}
if (flag) {
System.out.println(i);
}
}
}