(数学)灯泡亮灭问题
题目:
现在有10000个电灯,假设有10000个人经过这些电灯,当第1个人经过时,拉一下所有的灯,当第2个人经过时,拉一下所有2的倍数的灯,就这样,当第i个人经过时,就拉一下所有i的倍数的灯。假设所有灯的初始状态都是灭,那么当10000个人经过之后,还有多少灯是亮着的?
思路:
我们以10个灯泡,10个人为例,拉一下表示1,不拉表示0,横轴表示灯,竖轴表示人,因此可以得到以下的矩阵:
1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1
0 0 1 0 0 1 0 0 1 0
0 0 0 1 0 0 0 1 0 0
0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
可以看出,最后亮灯的就是1,4,9,因为它们被拉了奇数次。一种通用的方法就是将上述矩阵所有列进行异或操作,如果为1则亮,为0则灭。
那么亮灯的数字有什么规律吗?如上面的1,4,9....,好像很容易猜到是某个数的完全平方,为什么呢?我们来验证一下:
上面提到了,亮灯的是被拉了奇数次,而完全平方数的分解因子(即约数)一定为奇数个。下面通过归纳法来验证一下。
假设完全平方数为N,N=1*A^2,它的约数个数为奇数个;
假设A为质数,那么N的约数为1,A,N三个,为奇数;
假设A为完全平方数,那么N的约数为1,A,N,加上A的约数减去1和自身A,依旧为就奇数;
假设A为非完全平方数,那么N可以表示为A=B*C,这一步暂时不知怎么证明,但结果就是奇数;
总之,只有完全平方数,其约数个数为奇数,就是亮灯的情况。
因此,10000刚好为100的完全平方,因此有100盏灯亮着。
也可以通过代码来验证一下(很简单,通过两个循环就可以实现,这里就不贴代码了)