美团校招-2023.3.18.10点-第一题-小美抓敌人

目录

题目

 思想

C++代码实现


题目

美团校招-2023.3.18.10点-第一题-小美抓敌人_第1张图片

 输入:

3 1 1
1 1
1 2
1 3

输出

2

 思想

        利用前缀和进行优化,前缀和思想可以参考该文章搭配理解:https://blog.csdn.net/qq_53830608/article/details/130044441?spm=1001.2014.3001.5501

美团校招-2023.3.18.10点-第一题-小美抓敌人_第2张图片

 

  • 先求解输入初始数组(上图粉色+紫色区域)的前缀和。
  • 然后在该前缀和结果的基础上,枚举(A,B)右上端点位置,此时枚举的矩形为(i-a, j-b) 到 (i,j)之间。那为什么横纵的差值为A,B,枚举的位置只是矩形(i-a,j-b)->(i,j),没有(i,j)->(i+a,j+b)的范围内?
    • 因为该矩形的特点为每行输入的数据为2,它的列数是固定的。因此,(i,j)到(i+a,i+b)的矩阵内不能进行枚举搜索。
    • 拿示例而言,美团校招-2023.3.18.10点-第一题-小美抓敌人_第3张图片i=a+1,j=b+1时,对应到5的位置,可以看出没办法向(i+a,j+b)的方向走,只能往上面走
  • 然后在新枚举范围内,找出敌人的最大值。

 

C++代码实现

#include 
using namespace std;

int mp[1050][1050];//vector mp(1050,vector(1050,0));
int main()
{
    //先输入数据
    int n, a, b;
    cin >> n >> a >> b;
    while(n--) 
    {
      int x, y;
      cin >> x >> y;
      mp[x][y] ++;//mp记录敌人数量
    }
     //求前缀和
    for(int i = 1 ; i <= 1000 ; i ++) 
    {
        for(int j = 1 ; j <= 1000 ; j ++) 
        {
            mp[i][j] += mp[i-1][j] + mp[i][j-1] - mp[i-1][j-1];//直接在mp中更新
        }
    }
    int ans = 0;//存放结果
    
    for(int i = a+1 ; i <= 1000 ; i ++) 
    {
        for(int j = b+1 ; j <= 1000 ; j ++) 
        {
           int t = mp[i][j] - mp[i-a-1][j] - mp[i][j-b-1] + mp[i-a-1][j-b-1];
           ans = max(ans, t);
        }
     }
     cout << ans << endl;
     return 0;
}

如有异议欢迎指正!

文章内容仅为笔者学习记录笔记,如有侵权请与本人联系!

你可能感兴趣的:(算法,c++,算法)