Q03——翻牌
这里有 100 张写着数字 1~100 的牌,并按顺序排列着。最开始所有
牌都是背面朝上放置。某人从第 2 张牌开始,隔 1 张牌翻牌。然后第 2,
4, 6, …, 100 张牌就会变成正面朝上。
接下来,另一个人从第 3 张牌开始,隔 2 张牌翻牌(原本背面朝上
的,翻转成正面朝上;原本正面朝上的,翻转成背面朝上)。再接下来,
又有一个人从第 4 张牌开始,隔 3 张牌翻牌。
像这样,从第 n 张牌开始,每隔 n- 1 张牌翻牌,直到没有可翻动
的牌为止。
问题:求当所有牌不再变动时,所有背面朝上的牌的数字。
思路:只要根据问题描述,按顺序对牌进行翻转处理就可以了。用数组保
存牌的状态,如果牌正面朝上,则设置值为 true,反之为 false。这样一
来,我们就可以简单地模拟翻转操作了。用 Ruby 时,可以用下面这个
程序来实现。
# 初始化卡牌
N = 100
cards = Array.new(N, false)
# 从2到N翻牌
(2..N).each{|i|
j = i - 1
while (j < cards.size) do
cards[j] = !cards[j]
j += i
end
}
# 输出背面朝上的牌
N.times{|i|
puts i + 1 if !cards[i]
}
上述代码是用数组来实现的,但从左到右按顺序处理也就意
味着“已经翻转过的部分不再翻转”。如果针对这一点进行优化,还可
以继续简化程序,具体代码如下。
(1..100).each{|i|
flag = false
(1..100).each{|j|
if i % j == 0 then
flag = !flag
end
}
puts i if flag
}
答案:1,4,9,16,25,36,49,64,81,100