📜  门|门 CS 1996 |第 56 题(1)

📅  最后修改于: 2023-12-03 15:28:47.542000             🧑  作者: Mango

题目概述

这是一道题目来自于清华大学计算机科学与技术系1996年的《计算机算法程序设计竞赛》(CS 1996)中的第 56 题。

题目描述

有一排门,每一扇门的状态要么是开的,要么是关的。第一次从门头开始往后每隔一扇门关上一扇门,第二次从门头开始往后每隔两扇门操作(对关着的门开启,对开着的门关闭),第三次从门头开始往后每隔三扇门操作,……,以此类推,直到最后只剩一扇门为止。

现在的问题是,假设最初所有的门都是打开的,那么经过了这样的一系列操作以后,哪些门是关闭的。

输入格式

输入为一个正整数 $N$,$1<N<10^6$,表示有 $N$ 扇门。

输出格式

输出一个字符串,表示哪些门是关闭的。字符串中只包含数字,用空格隔开。如果有多个门是关闭的,输出的数字从小到大排序。

样例输入
5
样例输出
2 3 5
解题思路

可以模拟这个过程,使用一个数组表示每扇门的状态,初始化为全开。然后从一开始,每隔 $i$ 扇门进行一次操作。可以使用一个 for 循环来模拟这个过程,内层循环从 $i$ 开始,每次加 $i$,对于数组中对应的元素进行相应的操作。最后输出数组中值为 0 的下标即可。

参考代码

def closure_doors(n):
    doors = [1] * (n + 1)
    for i in range(1, n + 1):
        for j in range(i, n + 1, i):
            doors[j] = 1 - doors[j]
    result = [str(i) for i in range(1, n + 1) if doors[i] == 0]
    return ' '.join(result)

说明:

  • 代码使用了一个 dooor 数组存储每扇门的状态,1 表示门开着,0 表示门关着。
  • 对于每个操作循环从 $i$ 开始,每隔 $i$ 扇门进行一次操作,通过取反操作(1-门状态)改变门的状态。
  • 最后遍历数组,输出值为 0 的下标即可。
  • 上面的代码通过简单地对 list 对象应用 Python 的内置功能来实现解决方案。