P2241 统计方形(数据加强版)
题目链接:
本题其实是一道找规律题,对于 \(2 \times 3\) 的棋盘,可以试着找找看 \(1 \times 2\) 矩形的个数,不难发现对于 \(n \times m\) 的棋盘,\(a \times b\) 的矩形个数为:
① 横着的:\((n-a+1)(m-b+1)\)
② 竖着的(可理解为 \(m \times n\) 的棋盘,\(a \times b\) 的矩形):\((n-b+1)(m-a+1)\)
再将两者求和即可。
当 \(a\) 和 \(b\) 相等时就是正方形。
#include <cstdio>
using i64 = long long;
int n, m;
i64 cnt1, cnt2;//本题需要开long long
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i == j) cnt1 += (n - i + 1) * (m - j + 1);
else {
cnt2 += (n - i + 1) * (m - j + 1);
}
}
}
printf("%lld %lld", cnt1, cnt2);
return 0;
}
其实本题有数学公式,\(n \times m\) 的棋盘,所有矩形个数为
\(C_{n+1}^{2} \cdot C_{M+1}^{2}\)
往求正方形的个数即可。易知正方形的边长 \(a\) 满足 \(1 \leqslant a \leqslant \min(N, M)\)。
#include <cstdio>
#include <algorithm>
using i64 = long long;
i64 cnt1, cnt2, n, m;
int main()
{
scanf("%lld%lld", &n, &m);
cnt2 = ((n + 1) * n / 2) * ((m + 1) * m / 2);
for (int i = 1; i <= std::min(n, m); i++) {
cnt1 += (n - i + 1) * (m - i + 1);
}
printf("%lld %lld", cnt1, cnt2 - cnt1);
return 0;
}

浙公网安备 33010602011771号