求调
查看原帖
求调
1254085
ZJ_lzz楼主2024/11/18 21:35

求助各位大佬!!!

二维前缀和。

诈一看似乎是线段树/暴力?

首先第一个难点是题目说目标位于爆破正方形边上的不算。这个问题怎么解决。其实就可以把每个目标的坐标向右上角平移一位。

举个例子,(0, 0)和(1, 1),原本sum(1, 1)是2的(不符合题意);平移之后变成了(1, 1)和(2, 2),sum(1, 1)变成了1,符合题意。

第二个难点是题目说炸弹为正方形,所以以(i, j)为右上角的答案就不是简单的sum(i, j) = sum(i - 1, j) + sum(i, j - 1) - sum(i - 1, j - 1)了。而是在更新完sum后,每次ans取max,如下↓ ans = max(ans, sum(i, j) - sum(i - r, j) - sum(i, j - r)+ sum(i - r, j - r))

这样就能保证取到的ans是以(i, j)为右上角的正方形

不过...

#include <iostream>
#include <cstdio>
#define maxn 5005
using namespace std;
int n, r, ans;
int sum[maxn][maxn];
int main()
{
    cin>>n>>r;
    for(int i=1;i<=n;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        sum[x+1][y+1]=z;
    }
    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=r;i<=5000;i++)
    {
    	for(int j=r;j<=5000;j++)
        {
        	ans=max(ans,sum[i][j]-sum[i-r][j]-sum[i][j-r]+sum[i-r][j-r]);
		}
	} 
    cout<<ans;
    return 0;   
}

Orz

2024/11/18 21:35
加载中...