回 帖 发 新 帖 刷新版面

主题:1997年全国联赛复赛试题(初中组第1题)解答

1997年全国联赛复赛试题(初中组第1题)解答.
[问题描述]
   设有一个n*m的方格的棋盘(1<=m,n<=100),求该棋盘中包含有多少个正方形,多少个长方形(不包括正方形)。
   例如:当n=3,m=2时
正方形的个数有8个;即边长为1的正方形有6个;边长为2的正方形有2个;
长方形的个数有10个;即2*1的长方形有4个;1*2的长方形有3个;3*1的长方形有2个;3*2的长方形有1个。

程序要求:输入n和m,输出正方形个数与长方形的个数。
如上例题输入:3 2
        输出:8 ,10

[问题分析]
   首先对于n*m方格的棋盘中的任意的正方形而言,只要确定了左上角的位置和边长后,该正方形就完全确定了,如果两个正方形的左上角位置不同或左上角位置相同但边长不同,则这两个正方形显然不相同,因此只要穷举出最下面和最右边之外的所有格点(两条边的交叉点),算出以它们作为正方形的左上角位置时边长不同的正方形个数,然后累加起来即得到全部的正方形个数。同样地,以某一个格点为长方形的左上角位置的长方形(包括正方形)个数也可以类似地算出来,然后累加起来即得到全部的长方形个数,再去掉前面算出的正方形个数即为程序中要求的长方形个数了。

[算法分析]
   为了求出以某一个格点为正方形的左上角位置时的正方形个数,我们对所有的边进行编号,将从上到下的m+1条横向边定为第0行道第m行,将从左到右的n+1条纵向边定位第0列到第n列,这样以第i行与第j列的交叉点为正方形的左上角位置的正方形边长最大只能为m-i与n-j中的最小值,因此以第i行与第j列的交叉点为正方形的左上角位置的正方形个数为min(m-i,n-j),类似地以第i行与第j列的交叉点为正方形的左上角位置的长方形个数(包括正方形)(m-i)*(n-j)个,因为长方形的高可以取1到m-i中的任一值,长方形的宽可以取1到n-j中的任一值。


[程序清单]
program lt;
var i,j,m,n:longint;
    s:longint;
begin
  write('input n,m:');
  readln(n,m);
  s:=0;
  for i:=0 to n-1 do
  for j:=0 to m-1 do
    if n-i<m-j
     then s:=s+n-i
     else s:=s+m-j;
  write(s,' , ');
  s:=-s;
  for i:=0 to n-1 do
    for j:=0 to m-1 do s:=s+(n-i)*(m-j);
  writeln(s);
end.


希望大家支持支持下!如果有更好的方法,请立即告诉我!谢谢大家![em11]

回复列表 (共10个回复)

沙发

恩 真不错 现在很少有人对OI老试题做如此分析了  顶!!

板凳

8错8错~~~!~~顶起~

3 楼

丁页!!!大家来看看下面的OIBH站长刘汝佳所写的解析就知道这帖子绝对精品!
----------------------------------------------------------------
一、设有一个N*M方格的棋盘(l<=N<=100,1<=M<=100)(30%)
    求出该棋盘中包含有多少个正方形、多少个长方形(不包括正方形)。
    例如:当 N=2, M=3时:  
   
      正方形的个数有8个:即边长为1的正方形有6个;
                           边长为2的正方形有2个。
          长方形的个数有10个:
            即2*1的长方形有4个:
              1*2的长方形有3个:
              3*1的长方形有2个:
              3*2的长方形有1个:
    程序要求:输入:N,M
              输出:正方形的个数与长方形的个数
    如上例:输入:2  3
            输出:8,10
  
[分析]
题目够简单吧!直接套公式。不知道公式也可以,自己推吧。
根据乘法原理,先确定长方形的长的总个数,再确定宽。

4 楼

公式是什么????没看懂`~~

5 楼

就是说啊,所以说我们的楼主真的做的不错呢!!
为人民服务!

6 楼

为人民服务不收钱~

7 楼

收钱的那是领导干部,象偶们(还有楼主)做基层的,只是为人民服务啦`

8 楼

为人民(币)服务

9 楼

呵呵```真实在的一句话啊.....

10 楼

偶门们楼主要多发帖子,多给我们这些穷苦人民(币)加分呀!!

我来回复

您尚未登录,请登录后再回复。点此登录或注册