【HNOI2003】激光炸弹

【HNOI2003】 激光炸弹

一道二维前缀和,是一道比较经典的纯板子题目,针对这道题,我将再次进行二维前缀和的梳理

首先,要进行前缀和数组的推理得到d[i][j]+=d[i-1][j]+d[i][j-1]-d[i-1][j-1]

但是这也可以用以下代码实现:

for(int i=1;i<=maxn;i++)
	{
		for(int j=1;j<=maxn;j++)
		{
			a[i][j]+=a[i][j-1];
		}
	}
	for(int j=1;j<=maxn;j++)
	{
		for(int i=1;i<=maxn;i++)
		{
			a[i][j]+=a[i-1][j];
		}
	}

在求某一个区间值时,使用d[i][j]-d[i-1][j]-d[i][j-1]+d[i-1][j-1]

本道题就是一道板子,但是在处理循环的时候要避免以下问题:

例如:

const int maxn=5005;
int a[maxn][maxn];
for(int i=1;i<=maxn;i++)
{
    ...
}

会导致数据溢出,警钟长鸣

 

接下来是代码实现:

#include<bits/stdc++.h>
using namespace std;
const int maxn=5005;
int a[maxn+1][maxn+1];
int m;
int n;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int xx,yy,w;
		cin>>xx>>yy>>w;
		a[xx+1][yy+1]+=w;
	}
	int ans=-114514;
	for(int i=1;i<=maxn;i++)
	{
		for(int j=1;j<=maxn;j++)
		{
			a[i][j]+=a[i][j-1];
		}
	}
	for(int j=1;j<=maxn;j++)
	{
		for(int i=1;i<=maxn;i++)
		{
			a[i][j]+=a[i-1][j];
		}
	}
	
	for(int i=m;i<=maxn;i++)
	{
		for(int j=m;j<=maxn;j++)
		{
			int op=a[i][j]-a[i-m][j]-a[i][j-m]+a[i-m][j-m];
			ans=max(ans,op);
		}
	}
	cout<<ans;
}

 

posted @ 2024-09-10 19:17  Jucex  阅读(46)  评论(0)    收藏  举报