试题 G: 数正方形
时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分
【问题描述】
在一个 N × N 的点阵上,取其中 4 个点恰好组成一个正方形的 4 个顶点,
一共有多少种不同的取法?
由于结果可能非常大,你只需要输出模 10 9 + 7 的余数。
如上图所示的正方形都是合法的。
【输入格式】
输入包含一个整数 N。
【输出格式】
输出一个整数代表答案。
【样例输入】
4
【样例输出】
20【数据规模与约定】
对于所有评测用例,2 ≤ N ≤ 1000000。
又是一道送分题,比较简单。简单说一下思路:
(1)我们对数点阵上的方格不熟悉,但是对数正方形格子肯定很熟悉,因此,转化一下,n*n的点阵,就是边长为(n-1)的正方形。
(2)大正方形中包含多个小正方形,它们有平放的,有斜放的,为了便于计算,我们把两种形式分开:
我们代码中可以直接将得到的n进行减一操作,为了方便说明,我这里也直接将n作为大正方形的边长。
a)平放:把大小不一的正方形可以按边长从小到大排列,可以得到n种,边长从1到n
边长 个数
1 n*n
2 (n-1)*(n-1)
3 (n-2)*(n-2)
4 (n-3)*(n-3)
5 (n-4)*(n-4)
…… ……
n [n-(n-1)] * [n-(n-1)]
根据这个我们可以得到规律
边长为a的小正方形,结果为(n-a+1)*(n-a+1)个。
用程序求和就行了
b)斜放:
我画了一个不标准的图片,因为题目很简单,直接给出规律:
看图中的两个正方形,红色和蓝色,任意一个画有两段黑色线段,每个斜正方形都有这两条线段。
设两条黑色线段总长度之和为b,该斜正方形所占的面积刚好是一个平放正方形。这个平放正方形的边长恰好是b。
这不是偶然,是规律。找到这个之后就可以把斜正方形转化为平放正方形。然后进行 a)操作。
代码:(很少,主要是规律)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sn = new Scanner(System.in);
int n = sn.nextInt() - 1;
long count = 0;
long num = 1000000007;
//平放
// a 表示正方形边长
for (int a = 1; a <= n; a++) {
count += (n - a + 1) * (n - a + 1);
count%=num;
}
// 斜放
//i+j=斜正方形所占区域的边长=平放正方形的边长
//但i+j>=2,也就是平放正方形的边长从2开始
for (int i = 1; i <= n - 1; i++) {
for (int j = 1; j <= n - i; j++) {
count += (n - (i + j) + 1) * (n - (i + j) + 1);
count%=num;
}
}
System.out.println(count);
}
}