洛谷 - P2280 - 激光炸弹

https://www.luogu.org/problemnew/show/P2280

二维前缀和差分的模板题。注意学习二维前缀和的求法,不用又down又right的。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int sum[5005][5005];
int n,R;

void solve(){
    for(int j=1;j<=5000;j++)
        sum[0][j]+=sum[0][j-1];
    for(int i=1;i<=5000;i++)
        sum[i][0]+=sum[i-1][0];
    for(int i=1;i<=5000;i++){
        for(int j=1;j<=5000;j++){
            sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
        }
    }

    /*for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
            printf(" %d",g[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
            printf(" %d",sum[i][j]);
        }
        printf("\n");
    }
    printf("\n");*/

    int ans=sum[R-1][R-1];
    for(int j=R;j<=5000;j++)
        ans=max(ans,sum[R-1][j]-sum[R-1][j-R]);
    for(int i=R;i<=5000;i++)
        ans=max(ans,sum[i][R-1]-sum[i-R][R-1]);

    for(int i=R;i<=5000;i++){
        for(int j=R;j<=5000;j++){
            int tmp=sum[i][j]-sum[i-R][j]-sum[i][j-R]+sum[i-R][j-R];
            ans=max(ans,tmp);
        }
    }
    printf("%d\n",ans);

}


int main(){
    while(~scanf("%d%d",&n,&R)){
        R=min(R,5001);
        memset(sum,0,sizeof(sum));
        while(n--){
            int x,y,v;
            scanf("%d%d%d",&x,&y,&v);
            sum[x][y]+=v;
        }
        solve();
    }
}

猜你喜欢

转载自www.cnblogs.com/Yinku/p/10540055.html