面试的一个经典的智力题

6 篇文章 0 订阅
4 篇文章 0 订阅

             有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盏灯是亮着的


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值