这题到底在考什么
先数所有正方形,再用选线法数所有矩形,非正方形长方形 = 矩形总数 - 正方形数。
对象
正方形按边长 k 分类;矩形总数按选择两条横线和两条竖线计算。
为什么能这样做
边长 k 的正方形,左上角有 (n-k+1)(m-k+1) 种位置;矩形由边界线唯一确定。
先避开的坑
题目里的“长方形”不包含正方形,不能把矩形总数直接作为第二个答案。
样例 2 x 3
演示进度
课堂要求:每一步都让学生说出当前保留了什么信息,以及下一步为什么不会漏答案。
把关键过程写成表
| 类型 | 公式 | 样例值 |
|---|---|---|
| 1x1 正方形 | (2-1+1)(3-1+1) | 6 |
| 2x2 正方形 | (2-2+1)(3-2+1) | 2 |
| 所有矩形 | C(3,2) * C(4,2) | 18 |
| 非正方形 | 18 - 8 | 10 |
当堂检查
n x m 棋盘的横线有几条?
为什么必须用 long long?
代码读慢一点
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n, m;
cin >> n >> m;
long long sq = 0;
for (long long k = 1; k <= min(n, m); k++) {
sq += (n - k + 1) * (m - k + 1);
}
long long tot = (n * (n + 1) / 2) * (m * (m + 1) / 2);
cout << sq << " " << tot - sq << "\n";
return 0;
}
读代码抓这几处
- 正方形按边长从 1 枚举到 min(n,m)。
- 矩形总数用选线公式计算。
- 第二个输出是 tot - sq。
复杂度与常见错误
复杂度:时间 O(min(n,m)),空间 O(1)。
- 把第二个答案输出成矩形总数。
- 正方形边长循环上界写错。
- 使用 int 导致溢出。
源文件:GESP2/P2241.md · GESP2/P2241_solution.md