码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu P2280/ACAG 0x03-1 激光炸弹

时间:2019-12-04 22:08:48      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:define   二维   越界   $1   its   fine   pac   alc   print   

Luogu P2280/ACAG 0x03-1 激光炸弹

这道题要用到二维前缀和。
首先读入时,令$a[x][y]=val$;
然后不难递推出$s[i][j]=s[x-1][y]+s[i][j-1]-s[i-1][j-1]+a[i][j]$。
此处运用了容斥原理。
然后再遍历答案,不难得到,对于以$(x,y)$为右下角的格子,所得的价值为:$s[x][y]-s[x-r][y]-s[x][y-r]+s[x-r][y-r]$。
当然这道题有两个点需要注意:

  1. 目标点坐标范围为$[0,5000]$,可能会取到$0$,造成数组越界。对此我们只需要在将横、纵坐标均加$1$即可。
  2. 这道题有卡空间。所以可以只开$s$数组,并累加即可。
#include<bits/stdc++.h>
#define N 5010

using namespace std;

int n,r,ans;
int s[N][N];

int Calc(int x,int y) {
    return s[x][y]-s[x-r][y]-s[x][y-r]+s[x-r][y-r];
}

void Read() {
    scanf("%d%d",&n,&r);
    for(int i=1;i<=n;i++) {
        int x,y,val;
        scanf("%d%d%d",&x,&y,&val);
        s[x+1][y+1]=val;
    }
    return;
}

void Solve() {
    for(int i=1;i<=5001;i++) {
        for(int j=1;j<=5001;j++) {
            s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
        }
    }
    for(int i=r;i<=5001;i++) {
        for(int j=r;j<=5001;j++) {
            ans=max(ans,Calc(i,j));
        }
    }
    printf("%d",ans);
    return;
}

int main()
{
    Read();
    Solve();
    return 0;
}

Luogu P2280/ACAG 0x03-1 激光炸弹

标签:define   二维   越界   $1   its   fine   pac   alc   print   

原文地址:https://www.cnblogs.com/luoshui-tianyi/p/11985625.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!