题目:捕获敌人
题目描述
小美在玩一项游戏。该游戏的目标是尽可能抓获敌人。
敌人的位置将被一个二维坐标 (x,y)(x,y)(x,y) 所描述。
小美有一个全屏技能,该技能能一次性将若干敌人一次性捕获。捕获的敌人之间的横坐标的最大差值不能大于 AAA,纵坐标的最大差值不能大于 BBB 。
现在给出所有敌人的坐标,你的任务是计算小美一次性最多能使用技能捕获多少敌人。
输入描述
第一行三个整数 N,A,B,表示共有 N 个敌人,小美的全屏技能的参数 A 和参数 B。
接下来 N 行,每行两个数字 x,y,描述一个敌人所在的坐标。
1 ⩽ N ≤ 500 , 1 ⩽ A , B ⩽ 1000 , 1 ⩽ x , y ⩽ 1000 1⩽N≤500,1⩽A,B⩽1000,1⩽x,y⩽1000 1⩽N≤500,1⩽A,B⩽1000,1⩽x,y⩽1000
输出描述
一行,一个整数表示小美使用技能单次所可以捕获的最多数量。
样例1
输入
3 1 1
1 1
1 2
1 3
输出
2
说明:最多可以同时捕获两名敌人,可以是 (1,1) 和 )(1,2) 处的敌人,也可以是 (1,2) 和 (1,3) 处的敌人,但不可以同时捕获三名敌人,因为三名敌人时,纵坐标的最大差值是 2,超过了参数 B 的值 1。
样例2
输入
5 1 2
1 1
2 2
3 3
1 3
1 4
输出
3
说明:最多同时捕获三名敌人。其中一种方案如下: 捕获 (1,1),(1,3),(2,2) 处的三个敌人。
题解:
public class Test01 {
static final int N = 1000;
static int[][] g = new int[N + 10][N + 10];//敌人矩阵
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), a = sc.nextInt(), b = sc.nextInt();
a++; b++;//最大间隔++,前缀和下标从1开始处理,防止边界问题
a = Math.min(a, N);
b = Math.min(b, N);
//读入敌人的坐标
for(int i = 0;i < n;i++){
int x = sc.nextInt(),y = sc.nextInt();
g[x][y]++;
}
//二维前缀和预处理
for(int i = 1;i <= N;i++){
for(int j = 1;j <= N;j++){
g[i][j] = g[i - 1][j] + g[i][j - 1] - g[i -1][j - 1] + g[i][j];//二维前缀和公式一
}
}
//枚举一下所有长宽是ab的矩形,(i,j)为右下角,取max
int res = 0;
for(int i = a; i <= N; i++){
for(int j = b; j <= N; j++){
res = Math.max(res,g[i][j] - g[i - a][j] - g[i][j - b] + g[i - a][j - b]);//二维前缀和公式二
}
}
System.out.println(res);
}
}