程序员的算法趣题Q03——翻牌

Q03——翻牌

这里有 100 张写着数字 1~100 的牌,并按顺序排列着。最开始所有
牌都是背面朝上放置。某人从第 2 张牌开始,隔 1 张牌翻牌。然后第 2,
4, 6, …, 100 张牌就会变成正面朝上。
接下来,另一个人从第 3 张牌开始,隔 2 张牌翻牌(原本背面朝上
的,翻转成正面朝上;原本正面朝上的,翻转成背面朝上)。再接下来,
又有一个人从第 4 张牌开始,隔 3 张牌翻牌。
像这样,从第 n 张牌开始,每隔 n- 1 张牌翻牌,直到没有可翻动
的牌为止。
程序员的算法趣题Q03——翻牌_第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

你可能感兴趣的:(算法,算法)