美团笔试题【捕获敌人】

题目:捕获敌人

题目描述

小美在玩一项游戏。该游戏的目标是尽可能抓获敌人。

敌人的位置将被一个二维坐标 (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 1N5001A,B10001x,y1000

输出描述

一行,一个整数表示小美使用技能单次所可以捕获的最多数量。

样例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);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_44678607/article/details/129768845