P2241 统计方形(数据加强版)

组合计数 / 正方形枚举 / 矩形总数相减

一、先回答问题

这题到底在考什么

先数所有正方形,再用选线法数所有矩形,非正方形长方形 = 矩形总数 - 正方形数。

对象

正方形按边长 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 - 810
四、自己选答案

当堂检查

n x m 棋盘的横线有几条?
为什么必须用 long long?
五、C++14 参考代码

代码读慢一点

#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;
}

读代码抓这几处

六、收口

复杂度与常见错误

复杂度:时间 O(min(n,m)),空间 O(1)。

源文件:GESP2/P2241.md · GESP2/P2241_solution.md