题目描述
有一个 ×
方格的棋盘,求其方格包含多少正方形、长方形(不包含正方形)。
数据分析
输入
2 3
输出
8 10
一共有6个1×1的正方形,2个2×2的正方形。
一共有4个1×2的长方形,3个2×1的长方形,2个1×3的长方形,1个2×3的长方形。
解法分析
解法1:我们可以用四重循环遍历矩形左上角的xy坐标,右下角的xy坐标,但这样做算法复杂度为,显然不可行。
解法2:简化,用双重循环遍历,复杂度为。
解法3:确定一个矩形,只要确定矩形的四条边就可以了。要确定矩形的四条边,就要从n+1条横 线中选两条线,从m+1条竖线中选两条线,选法就是 ×
,根据排列组合公式,这个数是
×
,用单重循环算出正方形的个数后,用刚刚公式的值(矩形总个数)减去正方形的个数,就得到了长方形的个数,复杂度仅为
。
提示:计数的变量要用long long类型,不然会数据溢出,无法AC。
代码
解法2:
#include<bits/stdc++.h>
using namespace std;
long long n,m,rec,sqr;
int main() {
cin>>n>>m;
for(int i=0; i<n; i++)//循环,从n-0到n-(n-1)
for(int j=0; j<m; j++) {//循环,从m-0到m-(m-1)
if(i==j) sqr+=(n-i)*(m-j);//如果i==j,说明是正方形
else rec+=(n-i)*(m-j);//如果不等说明是矩形
}
cout<<sqr<<" "<<rec<<endl;//输出
return 0;
}
解法3:
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n,m,squ=0,rec=0;
cin>>n>>m;
long long cnt=n*(n+1)*m*(m+1)/4;//公式的计算
for(int i=1;i<=min(n,m);i++)squ+=(n-i+1)*(m-i+1);//求出正方形的个数
rec=cnt-squ;
cout<<squ<<" "<<rec;
return 0;
}
如有不足,欢迎大家指正补充。