Q 04 电子钟的亮灯数
IQ 70
目标时间:15 分钟
有一些电子钟使用了如图 1.6 中左图所示的七段数码管。这类时钟会根据时间决定显示屏上亮灯的数量。例如,在 12 时 34 分 56 秒时,电子钟会像图 1.6 中右图那样有 27 处亮灯。
图 1.6 七段数码管的亮灯位置
这里我们反过来进行思考,试着通过亮灯的数量来判断时间。但要注意,有些数字的排列组合并不能用来表示时间,例如 53:61:24 也有 27 处亮灯,但它就不在我们考虑的范围内。
另外,这类电子钟是 24 小时制,可以显示到 23 时 59 分 59 秒,再过 1 秒钟,时、分、秒就会都变为 0。
问题
当有 30 处亮灯时,能表示的时间有多少个?
思路
有好几种方法可以用来数电子钟亮灯处的数量。电子屏上有 6 个显示数字的地方,每个显示数字的地方可有 7 处亮灯,所以一共有处可亮灯。要查询这 42 处中有 30 处亮灯的情况,其实就是求从 42 个里选 30 个地方亮灯,有多少种排列组合的方式。这会是一个非常大的数。
但是,只有能用来表示时间的组合才会被显示出来,所以组合方式的数量要在可表示的时间的范围内计算。计算出来之后,再统计有多少处亮灯就可以得到答案了。
在求可以表示多少个时间时,程序可以写成代码清单 04.01 和代码清单 04.02 这样。
代码清单
04.01
(q04_1.rb
)
N = 30
# 返回两位数的亮灯数
def check(num)
light = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
light[num / 10] + light[num % 10]
end
cnt = 0
24.times do |h|
60.times do |m|
60.times do |s|
cnt += 1 if check(h) + check(m) + check(s) == N
end
end
end
puts cnt
代码清单
04.02
(q04_1.js
)
N = 30;
// 返回两位数的亮灯数
function check(num){
var light = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6];
return light[Math.floor(num / 10)] + light[num % 10];
}
var cnt = 0;
for (var h = 0; h < 24; h++){
for (var m = 0; m < 60; m++){
for (var s = 0; s < 60; s++){
if (check(h) + check(m) + check(s) == N)
cnt++;
}
}
}
console.log(cnt);
事先把已经计算过的结果存储起来,可以有效避免相同的数字被重复计算。代码清单 04.03 和代码清单 04.04 中就使用了这种方法,事先把 0 ~ 59 的数字存储到了数组中备用。
代码清单
04.03
(q04_2.rb
)
N = 30
# 返回两位数的亮灯数
def check(num)
light = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
light[num / 10] + light[num % 10]
end
lights = Array.new(60)
60.times do |i|
lights[i] = check(i)
end
cnt = 0
24.times do |h|
60.times do |m|
60.times do |s|
cnt += 1 if lights[h] + lights[m] + lights[s] == N
end
end
end
puts cnt
代码清单
04.04
(q04_2.js
)
N = 30;
// 返回两位数的亮灯个数
function check(num){
var light = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6];
return light[Math.floor(num / 10)] + light[num % 10];
}
var lights = new Array(60);
for (var i = 0; i < 60; i++){
lights[i] = check(i);
}
var cnt = 0;
for (var h = 0; h < 24; h++){
for (var m = 0; m < 60; m++){
for (var s = 0; s < 60; s++){
if (lights[h] + lights[m] + lights[s] == N)
cnt++;
}
}
}
console.log(cnt);
关键点
除了函数调用,数据库取值和文件导入等耗时的处理也可以事先执行。这种做法在实际工作中经常用到。
答案 8360 种