01 长方形内正方形与长方形的数量

在苏教版的五年级上册中,有一种经典的题目。 

“给定一格点长方形,请问在该长方形中,有多少个小格点正方形与小格点长方形?” Hcode OnlineJudge

我对这个问题写出了代码:

#include<iostream>
using namespace std;
string s;
bool flag=1;
int n=0,m=0,sum,tmp1,tmp2;
int main(){
    //输入并处理数据
    cout << "长方形的宽:"; 
    cin >> n;
    cout << "长方形的长:";
    cin >> m;
    n=min(n,m);
    m=max(n,m);
    //正方形
    for (int i=1;i<=n;i++)
        sum+=(n-i+1)*(m-i+1);
    cout << "这个长方形中有"<<sum << "个正方形。\n";
    //长方形
    for (int i=1;i<=m;i++){
        tmp2+=i;
        if (i==n)
            tmp1=tmp2;
    }cout << "这个长方形中有"<<tmp2*tmp1-sum << "个长方形(不包括正方形)\n";
    return 0;
}

//输入并处理数据


 

cout << "长方形的宽:"; 
cin >> n;
cout << "长方形的长:";
cin >> m;
n=min(n,m);
m=max(n,m);

输入之后,为了方便,自动设成了n<m。

格点正方形数量的计算

//正方形
for (int i=1;i<=n;i++)
    sum+=(n-i+1)*(m-i+1);
cout << "这个长方形中有"<<sum << "个正方形。\n";


正方形的计算方法是:
1×1正方形的个数+2×2正方形的个数+...+n×n正方形的个数。因为正方形的边长最大只能为小的n,不能是比n还要大的数。
而在计算正方形数量时,可以使用公式表示边长为i的格点正方形数量

f[i]=(n-i+1)*(m-i+1)

i表示正方形的边长。
在(n-i+1)中,计算的是正方形的边长在大长方形的宽上共有几种可能性。
在(m-i+1)中,计算的是正方形的边长在大长方形的长上共有几种可能性。
根据乘法原理“缺一不可”的原则,将其相乘,可以得到边长为i的正方形的个数。
最后全部相加,即可得到正方形的总个数。

长方形计算方式


长方形的通项公式推导相比起正方形的通项公式推导简单一些。
由于长方形的要求没有正方形那么苟刻,可以计算长与宽的可能性,最后再相乘。
 

//长方形
for(int i=1;i<=n;i++)
    tmp1+=i;
for(int i=1;i<=m;i++)
    tmp2+=i;
printf("这个长方形中有%d个长方形(不包括正方形)\n",tmp2*tmp1-sum);
//使用printf前请导入cstdio(C语言)库
(1+2+3+···+n-1+n)*(1+2+3+···+m-1+m)


这段代码是萌新的首选,毕竟简单又明了。但这题是NOIP1997的题目,就这样未免太没有水准了。我第一次提交的时候,就有几个测试点TLE了。所以,我们需要的是时间复杂度更优的,更快捷的代码。
因此我推导出了如此算法:

//长方形
for (int i=1;i<=m;i++){
    tmp2+=i;
    if (i==n)
        tmp1=tmp2;
    }
printf("这个长方形中有%d个长方形(不包括正方形)\n",tmp2*tmp1-sum);
//使用printf前请导入cstdio(C语言)库


由于在开始时已经设置了n<m,在这里就可以在计算m的累加时顺带计算n的累加。
在最后的算法,用tmp1×tmp2就可以得出总长方形的个数,非常没毛病。
但是,在这道题中有一道很关键的信息:不包括正方形的长方形。
因此我们需要把tmp1×tmp2的结果再减去正方形的总个数,也就是保存下来的sum。

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值