有100间房间,每个房间有一个电灯,可由拉灯绳控制开关,初始时 100 间全暗。将房间从1到100编号,现有100人,第一位拉能被1整除的房间灯绳一下,第二位拉能被2整除的房间灯绳一下...以此类推,直到第100位拉完。
问:最后有哪几间灯是亮的?
解:
以前就看到过这个题,说是搜狐的面试题吧,当时就觉得这个很简单啊,对于当时念大一的我都知道该怎么做.就定义一个100的数组,取0为灯不亮,1为灯亮,初始时全为0,然后,每次一个人去拉绳的时候,凡是能整除这个拉绳人的编号的灯的值都变一下,这样就可以得出了.
public static void main(String[] args) {
int total = 0; //统计最后还有几盏灯亮着
int []light = new int[101];
//i为人的编号,j为灯的编号
for(int i = 1; i < 101; i++) {
for(int j = i; j < 101; j++) {
if(j % i == 0) {
if(light[j] == 0)
light[j] = 1;
else
light[j] = 0;
}
}
}
for(int i = 1; i < 101; i++) {
if(light[i] == 1) {
System.out.print(i + "\t");
total++;
}
}
System.out.println("\n最后还有" + total + "盏灯是亮着的");
}
如今,有一次在网上看到这个题,标题为"面试智力题",兴趣来了,而且,大二的我思考问题也不会再那么单纯...然后,又想出来了一个方法.比如,6号灯,1,2,3,6这四个数字能整除6,所以6号灯经历"亮-暗-亮-暗"四次操作,为暗,得出一个结论,这个数的因子的个数为奇数个则最后是亮着的.
public static void main(String[] args) {
int total = 0; //统计最后还有几盏灯亮着
for(int i = 100; i > 0; i--) {
int count = 0; //用于记录因子的个数
for(int j = 1; j <= i; j++) {
if(i % j == 0)
count++;
}
if(count % 2 != 0) { //因子个数为奇数时,是亮着的,输出它,并让total加一
System.out.print(i + "\t");
total++;
}
}
System.out.println("\n最后还有" + total + "盏灯是亮着的");
}
显然,前一种方法也能得出结果,但方法未免太死了,也比较麻烦.显然,这个题目,你要是面试的时候按第一种方法做了...你死定了.....第一种方法是一个小学生都能想得出的方法啊......
不过,第二种方法还是不完美,因为看上去第二种并没有比第一种要简单多少...虽然,那个思想看上去要牛一些了....
然后,又再次发现,像上面的那个6的因子,1和6,2和3,总是这样成对出现的,但是,当这两个因子相同时,就只算一个,这样的话,因子数就为奇数了,而这样的数,必定是n=i*i这样的.所以,这个题变得非常简单了...100以内的这样的数,显然是对应的i为1-10,i为11时n就超过100的范围了.这样做的话,即使题目中的那个100改为更大的10000,10000000都能很快的解出来了
public static void main(String[] args) {
int total = 0; //统计最后还有几盏灯亮着
int i = 1;
while(i*i <= 100) {
System.out.print(i*i + "\t");
i++;
total++;
}
System.out.println("\n最后还有" + total + "盏灯是亮着的");
}
此题输出结果为:
1 4 9 16 25 36 49 64 81 100
最后还有10盏灯是亮着的