📌  相关文章
📜  门| Sudo GATE 2020 Mock II(2019 年 1 月 10 日)|第 32 题(1)

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

题目概述

这是 Sudo GATE 2020 Mock II 中的第32道题,考察的是程序员的逻辑思维和编程能力。

题目描述:

有一排门,从左到右依次编号为1到N。初始时,所有门都是关着的。有M个人,他们按照以下规定开关门:第一个人将门1到N中编号为1,4,7...的门打开;第二个人将编号为2,5,8...的门切换(如果开着则关上,如果关着则打开);第三个人将编号为3,6,9...的门切换;第四个人将编号为4,8,12...的门切换,以此类推。然后,第M个人结束操作。求最后有多少扇门是开着的?

例如,当有5个人时,我们按照以下步骤进行操作:

  1. 打开编号为1, 4的门;
  2. 切换编号为2, 5的门;
  3. 切换编号为3的门;
  4. 切换编号为4的门;
  5. 切换编号为5的门;

最终,编号为1,4的门是开着的。所以答案是2。

编写一个函数,输入N和M,输出最后开着的门的数量。

实现思路

首先可以先给每道门一个初始状态(关上),然后按照题目规定的顺序来模拟每个人对门的操作。最后统计开着的门的数量即可。

在模拟每个人的操作时,可以采用一个暴力的方法:对于每道门,判断它的编号是否符合当前操作所涉及的门的编号。符合则改变它的状态,否则不变。

但从实际编码来看,这样很可能会产生重复的代码、变量定义不明确等问题,不利于程序的维护和扩展。

使用数组可以简化代码逻辑,同时也容易扩展和维护。具体来说,可以定义一个大小为N的bool类型数组doors[],其中doors[i]表示第i扇门的状态。初始时,所有元素都被初始化为false,表示所有门都是关着的。

每个人对门的操作其实是对doors[i]进行改变,关着变成开着,开着变成关着。因此,可以在循环中使用以下逻辑:

对于第i个人,先定义一个变量i_step表示这个人对应的步长,然后从i_step开始,每隔i_step个门改变一个状态,具体来说,就是将j=i_step, i_step2, i_step3, …, j+N改变状态。

最后,遍历doors[]数组,统计其中值为true的元素的数量,即为开着的门数。

代码实现

以下是使用C++语言实现的代码片段:

int openDoors(int n, int m) {
    bool doors[n + 1] = {0};  // 初始化所有门都是关着的
    for (int i = 1; i <= m; i++) {  // 模拟每个人对门的操作
        int i_step = i;
        for (int j = i_step; j <= n; j += i_step) {
            doors[j] = !doors[j];  // 改变第j扇门的状态
        }
    }
    int count = 0;
    for (int i = 1; i <= n; i++) {
        if (doors[i]) count++;
    }
    return count;
}

总结

本题考察了编程能力的独立思考和代码实现能力。通过使用数组来优化代码逻辑,可以使程序更容易读懂、扩展和维护。除此之外,我们在编程过程中要严谨、注重变量名的定义,对于循环的边界条件也要注意。