如何求 在 n x m 个方格中找出所有长方形,正方形的个数

这篇博客探讨了如何计算一个n×m的二维网格中不同大小的长方形总数以及正方形数量。作者首先分析了长方形数量的计算方法,通过考虑长方形的长度l和宽度w的关系式(m-(w-1))*(n-(l-1))。接着,通过添加条件判断来计算正方形的数量。最后,给出了完整的C语言代码实现这一算法。

 思路 : 假设横向为n, 纵向为m 表格的长度为l,宽度为w,先考虑纵向 当 w = 1  l = 1 时 ,如图所示有三种可能 以 n = 2 , m = 3 为例

还是考虑纵向当 w = 2 l = 1时,如图所示有两种可能

 依次类推,对这列考虑的时候个数与其宽度 之间有个关系式 , m - w+1,

  接下来对行考虑也是这样 先固定w = 1 不变 ,依次考虑 l = 1 , l = 2 .... 可得 n-l+1

 则长方形的总个数为 (m-(w - 1))* (n-(l-1))

算出长方形后求正方形就简单了 直接加个判断语句l和w相等就行 ;

完整代码如下:

#include<stdio.h>
typedef long long ll;
int main()
{
ll z = 0, c = 0;
ll n , m;
scanf("%lld%lld",&n,&m);
for(int l = 1 ; l <= n ; l++)
{
for(int w = 1 ; w <= m ; w++)
{
int p = w-1, q =  l - 1;
if(p == q)z += (m - p)*(n-q);
else
c += (m - p)*(n-q);
}
}
printf("%lld %lld",z,c);
}

以下是几种不同实现方式的 C++ 代码来计算 n×m 方格棋盘中正方形的数量和长方形(不包含正方形)的数量: ### 方法一:根据数学公式计算 ```cpp #include <iostream> using namespace std; int main() { int m, n; cin >> m >> n; int t = n; int res1 = 0; int res2 = (m * (m + 1) / 2) * (n * (n + 1) / 2); for (int i = 0; i < t; i++) { res1 += m * n; m--; n--; } cout << res1 << " " << res2 - res1; return 0; } ``` ### 方法二:使用 `long long` 类型避免数据溢出 ```cpp #include <bits/stdc++.h> using namespace std; int main() { long long n, m; cin >> n >> m; long long a = 0, b = 0; long long sum; long long i = 0; while ((n - i) > 0 && (m - i) > 0) { a += (n - i) * (m - i); i++; } sum = (m * (m + 1) * n * (n + 1)) / 4; b = sum - a; cout << a << " " << b; return 0; } ``` ### 方法三:暴力枚举法 ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n, m; int zfx = 0; int cfx = 0; cin >> n >> m; for (int i = 0; i <= n; i++) { for (int j = 0; j <= m; j++) { for (int k = i + 1; k <= n; k++) { for (int l = j + 1; l <= m; l++) { int height = k - i; int width = l - j; if (height == width) { zfx++; } else { cfx++; } } } } } cout << zfx << " " << cfx; return 0; } ``` ### 方法四:另一种公式结合循环的实现 ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n, m, ans = 0, cnt = 0, bnu = 0; cin >> n >> m; for (int i = 1; i <= min(n, m); i++) { ans += (n - i + 1) * (m - i + 1); } for (int i = 1; i <= n; i++) cnt += n - i + 1; for (int i = 1; i <= m; i++) bnu += m - i + 1; cout << ans << " " << bnu * cnt - ans; return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值