[HNOI2003]激光炸弹

[HNOI2003]激光炸弹

http://www.nowcoder.com/questionTerminal/3df864279f5f4c03b809961f6815f165

题解写重了 参考https://blog.nowcoder.net/n/62b1d5cfab0647cbae38a868fdd0e713
本题图片说明
图片说明
按上图
设置M[i][j]记录以(1,1)为左上角端点 以(i,j)为右下角端点的矩形
大矩形=红色矩形+青色矩形-黑色重叠矩形+(i,j)点的数值
不难发现 按M[i][j]=M[i-1][j]+M[i][j-1]-M[i-1][j-1]+a[i][j]前缀即可
接下来直接枚举左上角(i,j)边长为k的正方形
M[i+k-1][j+k-1]-M[i+k-1][j-1]-M[i-1][j+k-1]+M[i-1][j-1]
注意细节 比如边界

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=5e3+7;
int  a[maxn][maxn];
int  M[maxn][maxn]={0};
int main()
{
  int  n,k;
  scanf("%d%d",&n,&k);
  memset(M,0,sizeof(M));
  int l=k,r=k;///这个很重要,最小的边界范围
  for (int i=0;i<n;++i)
  {
    int x,y,t;
    scanf("%d%d%d",&x,&y,&t);
    l=max(l,x+1);///寻找边界
    r=max(r,y+1);///寻找边界
    a[x+1][y+1]=t;
  }
  for (int i=1;i<=l;++i)
  {
    for (int j=1;j<=r;++j)
    {
        M[i][j]=M[i-1][j]+M[i][j-1]-M[i-1][j-1]+(a[i][j]);
    }
  }

  int  cnt=0;
  for (int i=1;i<=l-k+1;++i)///注意边界条件 只要l-i+1<=k即可
  {
    for (int j=1;j<=r-k+1;++j)///注意边界条件 只要r-i+1<=k即可
    {

      if (M[i+k-1][j+k-1]-M[i+k-1][j-1]-M[i-1][j+k-1]+M[i-1][j-1])///是i+k-1并非i+k 
    ///因为是从M[k]枚举到M[l]  
      {
        cnt=max(cnt,M[i+k-1][j+k-1]-M[i+k-1][j-1]-M[i-1][j+k-1]+M[i-1][j-1]);
      }
    }
  }
  printf("%d\n",cnt);
  return 0;
}
全部评论

相关推荐

2024-12-18 12:05
华东师范大学 golang
点赞 评论 收藏
分享
2024-12-23 12:44
门头沟学院 Java
黑皮白袜臭脚体育生:简历统一按使用了什么技术实现了什么功能解决了什么问题或提升了什么性能来写,如使用标签实现了兴趣推送,提升了用户黏性另外宣传下自己的开源仿b站微服务项目,GitHub已经390star,牛客上有完整文档教程,如果觉得有帮助的话可以点个小星星,蟹蟹
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务