题目
洛谷 P1548 [NOIP1997 普及组] 棋盘问题
[NOIP1997 普及组] 棋盘问题
题目背景
NOIP1997 普及组第一题
题目描述
设有一个 N × M N \times M N×M 方格的棋盘 ( 1 ≤ N ≤ 100 , 1 ≤ M ≤ 100 ) (1≤N≤100,1≤M≤100) (1≤N≤100,1≤M≤100)
求出该棋盘中包含有多少个正方形、多少个长方形(不包括正方形)。
例如:当 N = 2 , M = 3 N=2, M=3 N=2,M=3 时:
正方形的个数有 8 8 8 个:即边长为 1 1 1 的正方形有 6 6 6 个;边长为 2 2 2 的正方形有 2 2 2 个。
长方形的个数有 10 10 10 个:
即
- 2 × 1 2 \times 1 2×1 的长方形有 4 4 4 个:
- 1 × 2 1 \times 2 1×2 的长方形有 3 3 3 个:
- 3 × 1 3 \times 1 3×1 的长方形有 2 2 2 个:
- 3 × 2 3 \times 2 3×2 的长方形有 1 1 1 个:
输入格式
一行两个整数 N , M N,M N,M。
输出格式
一行两个整数,表示正方形的个数与长方形的个数。
样例 #1
样例输入 #1
2 3
样例输出 #1
8 10
想法
这道题,可以先数正方形和长方形一共有多少个,再单独数正方形有多少个,最后相减即可算出长方形个数。
第一步:数正方形、长方形总数。我们以 3 × 4 3\times4 3×4棋盘为例:
先看左上角,即第一行第一个,它连接右下方任意格点即可形成一个正方形或长方形。一共 3 × 4 = 12 3\times4=12 3×4=12个选择。
再处理第二个点,一共 2 × 4 = 8 2\times4=8 2×4=8个选择。
第3个点,一共 1 × 4 = 4 1\times4=4 1×4=4个选择。
对于第一行第四个点来说,有 0 × 4 = 0 0\times4=0 0×4=0个选择。
到了第二行第一个点,共 3 × 3 = 9 3\times3=9 3×3=9个选择。
第二个点, 2 × 3 = 6 2\times3=6 2×3=6个选择。
后面就不一一列举了,看下面这幅图:
所以,有 3 × 4 + 2 × 4 + 1 × 4 + 3 × 3 + 2 × 3 + 1 × 3 + 3 × 2 + 2 × 2 + 1 × 2 + 3 × 1 + 2 × 1 + 1 × 1 = 60 3\times4+2\times4+1\times4+3\times3+2\times3+1\times3+3\times2+2\times2+1\times2+3\times1+2\times1+1\times1=60 3×4+2×4+1×4+3×3+2×3+1×3+3×2+2×2+1×2+3×1+2×1+1×1=60个正方形和长方形。
由特殊到一般,对于大小为 x × y x\times y x×y的棋盘,正方形与长方形共有:
t = x y + x ( y − 1 ) + x ( y − 2 ) + ⋯ + x × 1 + ( x − 1 ) y + ( x − 1 ) ( y − 1 ) + ⋯ + ( x − 1 ) × 1 + ⋯ + 1 × 1 = [ x + ( x − 1 ) + ( x − 2 ) + ⋯ + 1 ] [ y + ( y − 1 ) + ( y − 2 ) + ⋯ + 1 ] = x ( x + 1 ) 2 × y ( y + 1 ) 2 = x y ( x + 1 ) ( y + 1 ) 4 \begin{aligned} &t=xy+x(y-1)+x(y-2)+\cdots+x\times1+(x-1)y+(x-1)(y-1)+\cdots+(x-1)\times1+\cdots+1\times1 \\&=[x+(x-1)+(x-2)+\cdots+1][y+(y-1)+(y-2)+\cdots+1] \\&=\frac{x(x+1)}{2}\times\frac{y(y+1)}{2} \\&=\frac{xy(x+1)(y+1)}{4} \end{aligned} t=xy+x(y−1)+x(y−2)+⋯+x×1+(x−1)y+(x−1)(y−1)+⋯+(x−1)×1+⋯+1×1=[x+(x−1)+(x−2)+⋯+1][y+(y−1)+(y−2)+⋯+1]=2x(x+1)×2y(y+1)=4xy(x+1)(y+1)
OK,现在只数正方形。还是以 3 × 4 3\times4 3×4棋盘为例:
先是最小的 1 × 1 1\times1 1×1正方形:共 3 × 4 3\times4 3×4个。
再是 2 × 2 2\times2 2×2正方形,共 2 × 3 = 6 2\times3=6 2×3=6个。
3 × 3 3\times3 3×3正方形: 1 × 2 = 2 1\times2=2 1×2=2
由于的棋盘最短边为 3 3 3,所以不可能再有 4 × 4 4\times4 4×4正方形。因此最大正方形的边长取决于棋盘最短边。
综上,共 3 × 4 + 2 × 3 + 1 × 2 = 20 3\times4+2\times3+1\times2=20 3×4+2×3+1×2=20个正方形。再由特殊推广到一般,对于大小为 x × y x\times y x×y的棋盘:令 k = m i n { x , y } k=min\{x,y\} k=min{x,y},其中 m i n { x , y } min\{x,y\} min{x,y}代表取 x , y x,y x,y中的最小值。
正方形的个数为:
s = x y + ( x − 1 ) ( y − 1 ) + ( x − 2 ) ( y − 2 ) + ⋯ + ( x − k ) ( y − k ) = x y + x y − x − y + 1 2 + x y − 2 x − 2 y + 2 2 + ⋯ + x y − k x − k y + k 2 = ( k + 1 ) x y − ( 1 + 2 + ⋯ + k ) ( x + y ) + ( 1 2 + 2 2 + 3 2 + ⋯ + k 2 ) = ( k + 1 ) x y − k ( k + 1 ) 2 ( x + y ) + ∑ i = 1 k i 2 = ( k + 1 ) x y − k ( k + 1 ) ( x + y ) 2 + k ( k + 1 ) ( 2 k + 1 ) 6 \begin{aligned} &s=xy+(x-1)(y-1)+(x-2)(y-2)+\cdots+(x-k)(y-k)\\ &=xy+xy-x-y+1^2+xy-2x-2y+2^2+\cdots+xy-kx-ky+k^2\\ &=(k+1)xy-(1+2+\cdots+k)(x+y)+(1^2+2^2+3^2+\cdots+k^2)\\ &=(k+1)xy-\frac{k(k+1)}{2}(x+y)+\sum^k_{i=1}i^2\\ &=(k+1)xy-\frac{k(k+1)(x+y)}{2}+\frac{k(k+1)(2k+1)}{6} \end{aligned} s=xy+(x−1)(y−1)+(x−2)(y−2)+⋯+(x−k)(y−k)=xy+xy−x−y+12+xy−2x−2y+22+⋯+xy−kx−ky+k2=(k+1)xy−(1+2+⋯+k)(x+y)+(12+22+32+⋯+k2)=(k+1)xy−2k(k+1)(x+y)+i=1∑ki2=(k+1)xy−2k(k+1)(x+y)+6k(k+1)(2k+1)
实现
- 输入。
- 根据刚才的公式直接代数据。
- 输出。
题解
C++
#include<iostream>
using namespace std;
int main(){int x,y;cin >> x >> y; //输入int k = min(x,y); //套公式int s = (k + 1) * x * y - k * (k + 1) * (x + y) / 2 + k * (k + 1) * (2 * k + 1) / 6; //正方形int t = (x + 1) * (y + 1) * x * y / 4; //正方形与长方形总数cout << s << ' ' << t - s; //输出return 0;
}
Python
x,y = input().split()
x = int(x)
y = int(y)
k = min(x,y)
s = (k + 1) * x * y - k * (k + 1) * (x + y) / 2 + k * (k + 1) * (2 * k + 1) / 6 #正方形
t = (x + 1) * (y + 1) * x * y / 4 #正方形与长方形总数
print(int(s),int(t - s)) #输出
难度
难度:★★☆☆☆
这道题还是有点难的,虽然放在第一题,但要想写出一个完美的程序还是需要推出公式,说白了这就是道数学题。等到公式推出来了,甚至连判断、循环语句都不需要了,代码简洁得很啊。
结尾
这道题你是怎么AC的?欢迎讨论哦!我们下期再见~