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;
}
posted @ 2024-04-01 13:03  胖柚の工作室  阅读(30)  评论(0)    收藏  举报