我今天在求职面试中遇到过这个问题,我完全被难过了。以下是对问题的描述:
你在房间内有一组1到100个灯,还有100个人。 i 第一个人走进房间并打开所有编号为 i 倍数的灯光。如果该灯已经打开,它们将关闭它(即它们将切换灯)。 100只是随机数 - 解决方案应该达到某个任意值 N (N ==灯数= =人数)。
例如,人1将打开所有灯(因为每个数字是1的倍数)。 Person 2将切换所有2的倍数(2,4,6,8等等)。这一直持续到第100个人。
当时,我觉得这可能与尝试确定N的素数有关,但我并不是100%肯定,所以我选择了一种蛮力的方法(这里大致相当)我在PHP中提供的内容:
function lights_toggled($number_of_lights) {
$toggly = function($idx, $lights) {
foreach($lights as $i => $light) {
if($i % $idx == 0) {
if($lights[$i]) {
$lights[$i] = 0;
} else if(!$lights[$i]) {
$lights[$i] = 1;
}
}
}
return $lights;
};
$lights = array_fill(1,$number_of_lights,0);
for($i = 1; $i <= count($lights); $i++) {
$lights = $toggly($i, $lights);
}
return array_sum($lights);
}
我认为一切都很好,直到我回到家并开始查看此功能的输入+输出。我做了这样的事情来得到一些样本结果:
$results = array();
for($j = 1; $j <= 100; $j++) {
$number_of_lights_on = lights_toggled($j);
$results[$number_of_lights_on][] = $j;
}
print_r($results);
很长,所以这里有一个输出的片段,用于当灯光开启时= = 3或4:
...
[3] => Array
(
[0] => 9
[1] => 10
[2] => 11
[3] => 12
[4] => 13
[5] => 14
[6] => 15
)
[4] => Array
(
[0] => 16
[1] => 17
[2] => 18
[3] => 19
[4] => 20
[5] => 21
[6] => 22
[7] => 23
[8] => 24
)
...
当灯光数量在9到15之间时,答案是3个灯亮。当灯的数量在16到24之间时,答案是4个灯亮。基本上,似乎当 x 灯作为答案返回时,总灯数的下限是 x ^ 2 ,它的上限是 x(x 2)
我开始在这里看到结构,但我不能指出这个结果是否遵循我不记得或不知道的算法。
答案 0 :(得分:9)
这个问题通常被称为&#34;储物柜问题&#34; - 网络上有很多解释,例如:
http://mathforum.org/library/drmath/view/55812.html
它的要点是具有偶数个除数的那个将最终处于它们的起始状态,而具有奇数个除数的那些将最终处于相反的状态。虽然除数很大,但是,因素是。
,这与素数有什么关系并没有多大关系。特别是,具有奇数除数的数字都是.... drumroll ...完美的正方形。因为除了平方根之外的任何其他除数将具有匹配且不相等的除数,但是完美的正方形具有一个额外的除数(平方根),其不与另一个除数配对;它与自己配对。
请注意,对于你所说的特定问题(有多少是开放的),这意味着对于floor(sqrt(N))
灯光的答案只是N
,因为那是多少完美的正方形将小于或等于N
。