[HNOI2003]激光炸弹(前缀和)

文章目录

    • 前缀和
    • 题目描述
    • 思考
    • AC代码

前缀和

容斥原理及其应用

题目描述

题目链接:

https://ac.nowcoder.com/acm/contest/999/A
[HNOI2003]激光炸弹(前缀和)_第1张图片

思考

首先二维前缀和代码

  for(int i=1;i<=x;i++)
    for(int j=1;j<=y;j++)
      a[i][j]+=a[i][j-1];

  for(int j=1;j<=y;j++)
    for(int i=1;i<=x;i++)
      a[i][j]+=a[i-1][j];

求长为r的正方形内所有数的和:

a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]

所有正方形和中最大的那一个:

ans=max(ans,a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]);

AC代码

#include 
#include 
#include 
#include 
#include
#include
#define Inf 1000000
using namespace std;

long long a[5050][5050];

int main(){
  int n,r;
  cin>>n>>r;
  int x=0,y=0;
  while(n--){
     int xx,yy,v;
     cin>>xx>>yy>>v;
      a[xx+1][yy+1]=v;//让下标从1开始
      x=max(xx+1,x);
      y=max(yy+1,y);
  }
  //r比x、y大的情况特殊判断
  x=max(x,r),y=max(y,r);
  for(int i=1;i<=x;i++)
    for(int j=1;j<=y;j++)
      a[i][j]+=a[i][j-1];

  for(int j=1;j<=y;j++)
    for(int i=1;i<=x;i++)
      a[i][j]+=a[i-1][j];

  long long ans=0;
  for(int i=r;i<=x;i++){
    for(int j=r;j<=y;j++){
        //cout<
      ans=max(ans,a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]);
    }
  }
  cout<<ans<<endl;
}

你可能感兴趣的:(#,递推与递归)