拼图 | 1000 个路过的人打开/关闭 1000 个灯泡
有1000个灯泡和1000人。所有灯泡最初都是关闭的。第 1 个人去翻转灯泡 1、2、3、4,……第 2 个人然后翻转 2、4、6、8,……第 3 个人,然后是 3、6、9,……等等,直到所有 1000 个人都完成了。 25、93、576、132、605、26、45、37、36 的灯泡在所有人都翻转了各自的灯泡后是什么状态?是否有预测灯泡状态的通用解决方案?在 1000 人过去之后,有多少个灯泡亮着?
说明:主要观察结果是:
- 人 1 翻转灯泡 1、2、3,……,它们是 1 的倍数。
- 人 2 翻转了灯泡 2、4、6,……,它们是 2 的倍数。
- 人 3 翻转灯泡 3、6、9,……,它们是 3 的倍数。
- 类似地,人 1000 翻转灯泡 1000,它是 1000 的倍数。
- 从上面的观察,我们可以说那个人 i 会翻转 i 的倍数的灯泡,
- 因此,一个灯泡 j 将被所有 j 是其人数的倍数的人翻转。换句话说,灯泡 j 将被所有 i 是 j 因子的人翻转,
- 例子:
- (i)灯泡 10 将被人数为 10 的人 1、2、5、10 翻转。
- (ii)灯泡 12 将被人数为 12 的人 1、2、3、4、6、12 翻转。
- (i)灯泡 10 将被人数为 10 的人 1、2、5、10 翻转。
- 因此,灯泡 25 将被人 1、5、25 翻转,因此它将被翻转 3 次,这是奇数,因为最初,所有灯泡都“关闭”,现在灯泡 25 将“打开”。
- 灯泡 93 将被人 1、3、31、93 翻转,因此它将翻转 4 次,这是均匀的,因为最初所有灯泡都“关闭”,现在灯泡 93 将“关闭”。
- 灯泡 576 将被 1、2、3、4、6、8、9、12、16、18、24、32、36、48、64、72、96、144、192、288、576 人翻转,所以它会翻转 21 次,这很奇怪,因为最初,所有灯泡都“关闭”,现在灯泡 576 将“打开”。
- 灯泡 132 将被人 1、2、3、4、6、11、12、22、33、44、66、132 翻转,因此它将翻转 12 次,这是均匀的,并且由于最初,所有灯泡被“关闭”,现在灯泡 132 将“关闭”。
- 灯泡 605 将被人 1、5、11、55、121、605 翻转,因此它将被翻转 6 次,这是均匀的,因为最初,所有灯泡都“关闭”,现在灯泡 605 将是“离开”。
- 灯泡 26 将被人 1、2、13、26 翻转,因此它将翻转 4 次,这是均匀的,因为最初,所有灯泡都“关闭”,现在灯泡 26 将“关闭”。
- 灯泡 45 将被人 1、3、5、9、15、45 翻转,所以它会翻转 6 次,这是均匀的,因为最初,所有灯泡都“关闭”,现在灯泡 45 将是“离开”。
- 灯泡 37,作为素数的灯泡,将被人 1、37 翻转,因此它将翻转 2 次,这是偶数,因为最初,所有灯泡都“关闭”,现在灯泡 37 将“关闭” ”。
- 灯泡 36 将被人 1、2、3、4、6、9、12、18、36 翻转,因此它将翻转 9 次,这是奇数,因为最初,所有灯泡都“关闭”,现在灯泡 36 将“打开”。
要找出给定灯泡的状态:
我们计算灯泡个数的因子个数,根据上面的观察,如果因子个数为奇数,则灯泡“亮”,如果为偶数,则“灭”结束。
找出最终将“打开”多少个灯泡的算法:
我们从 1 到 1000 计算每个数字的因数。如果任何数字的因数是奇数,则相应的灯泡“亮”,因此我们更新结果,最后打印出来。
下面是实现上述算法的代码。
C++
// C++ implementation of above approach
#include
using namespace std;
int findOnBulbs(int numberOfBulbs)
{
// initializing the result
int onBulbs = 0;
// to loop over all bulbs from 1 to numberOfBulbs
int bulb = 1;
// to loop over persons to check whether their person number
int person = 1;
// is a factor of light bulb number or not
for (bulb = 1; bulb <= numberOfBulbs; bulb++) {
// inner loop to find factors of given bulb
// to count the number of factors of a given bulb
int factors = 0;
for (person = 1; person * person <= numberOfBulbs; person++) {
if (bulb % person == 0) // person is a factor
{
factors++;
// bulb != person*person
if (bulb / person != person)
{
factors++;
}
}
}
// if number of factors is odd, then the
if (factors % 2 == 1)
{
// light bulb will be "on" in the end
cout << "Light bulb "
<< bulb
<< " will be on"
<< "\n";
onBulbs++;
}
}
return onBulbs;
}
// Driver program to test above function
int main()
{
// total number of light bulbs
int numberOfBulbs = 1000;
// to find number of on bulbs in
// the end after all persons have
// flipped the light bulbs
int onBulbs = findOnBulbs(numberOfBulbs);
cout << "Total "
<< onBulbs
<< " light bulbs will be on in the end out of "
<< numberOfBulbs
<< " light bulbs"
<< "\n";
return 0;
}
Java
// Java implementation of the
// above given approach
public class GFG
{
static int findOnBulbs(int numberOfBulbs)
{
// initializing the result
int onBulbs = 0;
// to loop over all bulbs from 1 to numberOfBulbs
int bulb = 1;
// to loop over persons to check whether their person number
int person = 1;
// is a factor of light bulb number or not
for (bulb = 1; bulb <= numberOfBulbs; bulb++) {
// inner loop to find factors of given bulb
// to count the number of factors of a given bulb
int factors = 0;
for (person = 1; person * person <= numberOfBulbs; person++) {
if (bulb % person == 0) // person is a factor
{
factors++;
// bulb != person*person
if (bulb / person != person)
{
factors++;
}
}
}
// if number of factors is odd, then the
if (factors % 2 == 1)
{
// light bulb will be "on" in the end
System.out.println("Light bulb " + bulb + " will be on");
onBulbs++;
}
}
return onBulbs;
}
// Driver program to test above function
public static void main(String [] args)
{
// total number of light bulbs
int numberOfBulbs = 1000;
// to find number of on bulbs in
// the end after all persons have
// flipped the light bulbs
int onBulbs = findOnBulbs(numberOfBulbs);
System.out.println("Total " + onBulbs
+ " light bulbs will be on in the end out of "
+ numberOfBulbs + " light bulbs");
}
// This code is contributed
// by Ryuga
}
Python3
# Python3 code implementing the
# given approach
def findOnBulbs(numberOfBulbs):
# initializing the result
onBulbs = 0
# to loop over all bulbs from
# 1 to numberOfBulbs
bulb = 1
# to loop over persons to check
# whether their person number
person = 1
# Is a factor of light bulb number or not
for bulb in range(1, numberOfBulbs + 1):
# inner loop to find factors of
# given bulb to count the number
# of factors of a given bulb
factors = 0
for person in range(1, int(numberOfBulbs**(0.5)) + 1):
if bulb % person == 0: # person is a factor
factors += 1
# bulb != person*person
if bulb // person != person:
factors += 1
# if number of factors is odd, then the
if factors % 2 == 1:
# light bulb will be "on" in the end
print("Light bulb", bulb, "will be on")
onBulbs += 1
return onBulbs
# Driver Code
if __name__ == "__main__":
# total number of light bulbs
numberOfBulbs = 1000
# to find number of on bulbs in
# the end after all persons have
# flipped the light bulbs
onBulbs = findOnBulbs(numberOfBulbs)
print("Total", onBulbs, "light bulbs will",
"be on in the end out of",
numberOfBulbs, "light bulbs")
# This code is contributed
# by Rituraj Jain
C#
// C# implementation of above approach
using System;
class GFG
{
static int findOnBulbs(int numberOfBulbs)
{
// initializing the result
int onBulbs = 0;
// to loop over all bulbs from 1 to numberOfBulbs
int bulb = 1;
// to loop over persons to check whether their person number
int person = 1;
// is a factor of light bulb number or not
for (bulb = 1; bulb <= numberOfBulbs; bulb++) {
// inner loop to find factors of given bulb
// to count the number of factors of a given bulb
int factors = 0;
for (person = 1; person * person <= numberOfBulbs; person++) {
if (bulb % person == 0) // person is a factor
{
factors++;
// bulb != person*person
if (bulb / person != person)
{
factors++;
}
}
}
// if number of factors is odd, then the
if (factors % 2 == 1)
{
// light bulb will be "on" in the end
Console.WriteLine("Light bulb " + bulb + " will be on");
onBulbs++;
}
}
return onBulbs;
}
// Driver program to test above function
public static void Main()
{
// total number of light bulbs
int numberOfBulbs = 1000;
// to find number of on bulbs in
// the end after all persons have
// flipped the light bulbs
int onBulbs = findOnBulbs(numberOfBulbs);
Console.WriteLine("Total " + onBulbs
+ " light bulbs will be on in the end out of "
+ numberOfBulbs + " light bulbs");
}
}
// This code is contributed
// by Akanksha Rai
PHP
Javascript
C++
#include
#include
using namespace std;
int main()
{
int numberOfBulbs = 1000;
int root = sqrt(numberOfBulbs);
for (int i = 1; i < root + 1; i++)
{
cout << "Light bulb " << (i * i)
<< " will be on" << endl;
}
cout << "Total " << root
<< " light bulbs will be on in the end out of "
<< numberOfBulbs << " light bulbs" << endl;
return 0;
}
// This code is contributed by Apurvaraj
Java
import java.io.*;
class GFG {
// Driver code
public static void main (String[] args) {
int numberOfBulbs = 1000;
int root = (int) Math.sqrt(numberOfBulbs);
for (int i = 1; i < root + 1; i++)
{
System.out.println("Light bulb " + (i * i) +" will be on");
}
System.out.println("Total " + root
+ " light bulbs will be on in the end out of "
+ numberOfBulbs + " light bulbs");
}
}
// This code is contributed b ab2127.
Python3
import math
root = int(math.sqrt(1000))
for i in range(1, root + 1):
print("Light bulb %d will be on"%(i * i))
print("""Total %d light bulbs will be on
in the end out of 1000 light bulbs"""%root)
C#
using System;
using System.Collections.Generic;
class GFG
{
// Driver code
public static void Main(String [] args)
{
int numberOfBulbs = 1000;
int root = (int) Math.Sqrt(numberOfBulbs);
for (int i = 1; i < root + 1; i++)
{
Console.WriteLine("Light bulb " + (i * i) +" will be on");
}
Console.WriteLine("Total " + root
+ " light bulbs will be on in the end out of "
+ numberOfBulbs + " light bulbs");
}
}
// This code is contributed by 29AjayKumar
Javascript
前面的程序是用 O(n*sqrt(n)) 编写的。
从观察中可以清楚地看出,只要因子数为奇数,灯泡就会亮起。
对于每个除数的任何非平方数,都有一个相应的商,因此因子的数量将是偶数。
对于每个平方数,当我们将它除以它的平方根时,商将是相同的数,即它的平方根。所以它有奇数个因素。
因此,我们可以为这个问题编写一个高效的代码,计算时间为 O(sqrt(n))。
C++
#include
#include
using namespace std;
int main()
{
int numberOfBulbs = 1000;
int root = sqrt(numberOfBulbs);
for (int i = 1; i < root + 1; i++)
{
cout << "Light bulb " << (i * i)
<< " will be on" << endl;
}
cout << "Total " << root
<< " light bulbs will be on in the end out of "
<< numberOfBulbs << " light bulbs" << endl;
return 0;
}
// This code is contributed by Apurvaraj
Java
import java.io.*;
class GFG {
// Driver code
public static void main (String[] args) {
int numberOfBulbs = 1000;
int root = (int) Math.sqrt(numberOfBulbs);
for (int i = 1; i < root + 1; i++)
{
System.out.println("Light bulb " + (i * i) +" will be on");
}
System.out.println("Total " + root
+ " light bulbs will be on in the end out of "
+ numberOfBulbs + " light bulbs");
}
}
// This code is contributed b ab2127.
Python3
import math
root = int(math.sqrt(1000))
for i in range(1, root + 1):
print("Light bulb %d will be on"%(i * i))
print("""Total %d light bulbs will be on
in the end out of 1000 light bulbs"""%root)
C#
using System;
using System.Collections.Generic;
class GFG
{
// Driver code
public static void Main(String [] args)
{
int numberOfBulbs = 1000;
int root = (int) Math.Sqrt(numberOfBulbs);
for (int i = 1; i < root + 1; i++)
{
Console.WriteLine("Light bulb " + (i * i) +" will be on");
}
Console.WriteLine("Total " + root
+ " light bulbs will be on in the end out of "
+ numberOfBulbs + " light bulbs");
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
Light bulb 1 will be on
Light bulb 4 will be on
Light bulb 9 will be on
Light bulb 16 will be on
Light bulb 25 will be on
Light bulb 36 will be on
Light bulb 49 will be on
Light bulb 64 will be on
Light bulb 81 will be on
Light bulb 100 will be on
Light bulb 121 will be on
Light bulb 144 will be on
Light bulb 169 will be on
Light bulb 196 will be on
Light bulb 225 will be on
Light bulb 256 will be on
Light bulb 289 will be on
Light bulb 324 will be on
Light bulb 361 will be on
Light bulb 400 will be on
Light bulb 441 will be on
Light bulb 484 will be on
Light bulb 529 will be on
Light bulb 576 will be on
Light bulb 625 will be on
Light bulb 676 will be on
Light bulb 729 will be on
Light bulb 784 will be on
Light bulb 841 will be on
Light bulb 900 will be on
Light bulb 961 will be on
Total 31 light bulbs will be on in the end out of 1000 light bulbs