📅  最后修改于: 2023-12-03 14:58:24.287000             🧑  作者: Mango
有 $2$ 个人,$A$ 和 $B$,在一个有 $n$ 个门的走廊上玩游戏。最初所有门都是关闭的。$A$ 开始,他经过每扇门都打开它,然后每第二扇门再次关闭。接下来,$B$ 经过每第三扇门,如果该门开着,则关闭它;如果该门关闭,则打开它。继续这个过程,依次找到第 $k$ 个人,重复这个操作。问最后门的状态是打开的还是关闭的?
第一个参数为 $n$,表示有 $n$ 个门 $( 1 \leq n \leq 10^6)$。
第二个参数为 $k$,表示有 $k$ 个人 $( 1 \leq k \leq 10^3)$。
如果最后门的状态是打开的,则输出 open
,否则输出 closed
。
输入:
10 2
输出:
closed
通过观察题目,可以得出以下结论:
如果一个门被经过了偶数次,则门的状态会是关闭的。
如果一个门被经过了奇数次,则门的状态会是打开的。
如果经过 i 个门,则第 i 个门一定会被打开。
通过上述结论可以得出,每个人经过经过的门的状态只与门的编号有关,可以用一个 bool 数组 doors
维护门的状态。
我们可以按照题意模拟这个过程,对于每个人对应的门进行状态处理,最终统计打开的门的数量,判断门的状态是否是打开的。
设门的数量为 $n$,人的数量为 $k$,时间复杂度为 $\mathcal{O}(nk)$。
时间复杂度为 $\mathcal{O}(nk)$。
空间复杂度为 $\mathcal{O}(n)$,即 bool 数组 doors
的空间。
bool doors[maxn];
void play(int n) {
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j += i) {
doors[j] ^= 1;
}
}
}
int main() {
int n, k;
cin >> n >> k;
play(k);
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (doors[i]) cnt++;
}
if (cnt % 2 == 0) {
cout << "closed" << endl;
} else {
cout << "open" << endl;
}
return 0;
}
注:为了避免函数传递数组时需要传递数组长度的问题,此代码直接将数组大小定义为常量 maxn
,且数组下标从 $1$ 开始。