题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝在一张无限大的特殊画布上作画。
这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)(0,0),(2020,11),(11,14),(2000,2000)。
只有这几个格子上有黑色,其它位置都是白色的。
每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。
请问,经过 20202020 分钟后,画布上有多少个格子是黑色的。
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
解析:如下图所示,一个点扩散3分钟后,它是呈这种菱形的
它的边界点,也就是最外边我画红线这些点,它们的坐标减去中心点的坐标的距离的绝对值之和,是刚好等于3的。比如边界点的坐标为(a,b),中心的的坐标为(x,y),则|a-x|+|b-y|=3,其实仔细观察,只要是属于这个菱形的点,离这个中心点的距离都是小于等于3的,当然这里这个距离是指上面说的这个坐标之差的绝对值再加起来哈。所以我们可以根据这个性质来判断哪些点是属于中心点的扩散范围的。这里一共有4个中心点, 它们扩散2020分钟后肯定是会交叉的,没关系,我们把这四个点扩散后的区域想成一个矩形,在这个矩形里我们一一枚举符合条件的点计数,就是最后的答案。
以上四张图就是四个中心点扩散2020分钟后的上下左右边界点的坐标,然后我们在其中找出最边上的坐标,确定包含四个菱形的矩形边界,如下图:
这样我们就确定了这个四个扩散范围的边界。然后我们在这个范围一一枚举每个点离中心点的“距离”是不是小于等于2020就好了。这里的范围是6060*6040=36602400,还不到一亿,对于填空题还是很小的数据范围了。
import static java.lang.Math.abs;
public class Main {
public static void main(String[] args) {
int res = 0;
for (int x = -2020; x <= 4040; x++) {
for (int y = -2020; y <= 4020; y++) {
int a = abs(x - 2000) + abs(y - 2000);
if (a <= 2020) {
res ++;
}else {
a = abs(x - 11) + abs(y - 14);
if (a <= 2020) {
res++;
}else {
a = abs(x - 2020) + abs(y - 11);
if (a <= 2020) {
res++;
}else {
a = abs(x) + abs(y);
if (a <= 2020) {
res++;
}
}
}
}
}
}
System.out.print(res);
}
}