A 魔方 - 顺序结构

求一个 $n$ 阶魔方的角块,棱块,中心块的数量。
  • 角块永远为 $8$ 个,直接输出即可。
  • 棱块为 $12 \times (n - 2)$ 个,输出这个式子的结果即可。
  • 中心块为 $6 \times (n - 2)^2$ 个。注意到,这个式子里出现了乘方,然而我们并没有学过乘方如何计算。考虑二次方的本质,其实是两个 $(n - 2)$ 相乘,因此输出 $6 \times (n - 2) \times (n - 2)$ 的结果即可。

值得注意的是,如果你使用 pow 函数,输出时需要转换为整数类型,否则在面临较大数据时会以科学计数法的形式输出。

#include <iostream>
using namespace std;

int n;

int main() {
    cin >> n;
    cout << "8 " << 12 * (n - 2) << ' ' << 6 * (n - 2) * (n - 2) << endl;
    return 0;
}

B 学校 - 分支结构

三栋楼图书馆、综合楼、艺术楼的楼层分别为 $3,5,9$,人流量分别为 $a,b,c$。

已知目标教室的楼层 $n$,并且所在教学楼是可能的教学楼当中人流量最小的一栋,输出其名字。

  • 本题要依次判断两个条件,第一个是楼层限制,第二个是人流量。只需按照题意依次判断即可:

    • 如果 $n \le 3$,则三栋楼都需要考虑,就应该从 $a,b,c$ 三个中判断出最少的,输出对应的名字。
    • 如果 $3 < n \le 5$,则只可能在综合楼和艺术楼里,就应该从 $b,c$ 两个中判断哪一个较少,输出对应的名字。
    • 如果 $5 < n \le 9$,则只可能在艺术楼里,直接输出其名字即可。
  • 此外,输出时,如果担心出现偏差,可以直接复制题目给出的字符串。
#include <iostream>
using namespace std;

int n, a, b, c;

int main() {
    cin >> n >> a >> b >> c;  // cin 会忽略空格和换行,一次性输入即可
    if (n <= 3) {
        if (a < b && a < c) cout << "library" << endl;
        else if (b < a && b < c) cout << "comprehensive" << endl;
        else cout << "art" << endl;
    } else if (n > 3 && n <= 5) {  // 只考虑 b, c 即可
        if (b < c) cout << "comprehensive" << endl;
        else cout << "art" << endl;
    } else cout << "art" << endl;  // 大于 5 则直接输出 art 即可
    return 0;
}

C 教室 - 循环结构与简单数学推导

有 $n$ 个柜子,第 $i$ 个柜子有 $a_i \times b_i$ 个格子,每个格子由 $c_i$ 个学生使用。

因此得到学生总数与桌子总数,按照指定列数来摆桌子,尽量摆成整齐的矩形,多余的放到最后一排的后方,求最后的排数最后一排桌子的张数

  • 本题一共分两个部分,第一个部分是求出桌子总数,第二个部分是求出摆好之后桌子的排数和最后一排的桌子数量。
  • 对于第一部分,显然,对于第 $i$ 个柜子,应该有 $a_i \times b_i \times c_i$ 个学生使用,将所有的柜子对应的学生个数累加就得到了学生总数,等于桌子总数。
  • 接着就是第二部分。不难发现,桌子的排数应该是总数除以列数并向上取整
  • 因为如果恰好整除,则排数等于总数除以列数,否则,等于其加一。
  • 这里给出一个结论,$\lceil \frac{a}{b} \rceil = \lfloor \frac{a + b - 1}{b} \rfloor$,$a,b$ 为整数且 $b > 0$,请各位自行证明($\lceil \ \rceil$ 代表向上取整,$\lfloor \ \rfloor$ 代表向下取整,这与我们数学教材上的取整符号有所不同,请注意区分)。这个结论可以帮助我们简化代码,无需额外写一个判断语句,简洁清晰。
  • 然后,我们假设学生总数为 $sum$,那么对于最后一排的桌子数量,显然就等于 $sum \bmod m$ 了。
  • 值得注意的是,当能够整除时,桌子摆成了矩形,最后一排的桌子数量等于 $m$,但此时 $sum \bmod m = 0$,所以要特判(就是判断特殊情况)。
#include <iostream>
using namespace std;

int n, m, a, b, c, sum;

int main() {
    cin >> n >> m;
    while (n--) cin >> a >> b >> c, sum += a * b * c;  // 使用逗号可将多个语句合并为一句
    cout << (sum + m - 1) / m << ' ';  // 排数等于总人数除以列数的向上取整
    if (sum % m == 0) cout << m << endl;  // 如果正好可以排成一个矩形,则最后一排的人数等于列数
    else cout << sum % m << endl;  // 否则输出最后一排的人数
    return 0;
}

对于上面的代码,出现了 while (n--) 这样的语句,它在这里等价于:

while (n > 0) {
    // 循环体
    n--;
}

因为 n-- 等价于 n = n - 1,也就是每次给 $n$ 减去 $1$,所以 $n$ 在不等于 $0$ 的时候,循环条件是成立的,当 $n$ 为 $0$ 时(也就是循环条件的值为 $0$),循环结束。

另外,上面的 while 循环也可以改成 for 循环:

for (int i = 1; i <= n; ++i)
    cin >> a >> b >> c, sum += a * b * c;
最后修改:2024 年 02 月 03 日
如果觉得我的文章对你有用,请随意赞赏