题目详情

alt

输入样例:

2 1
0 0 1
1 1 1

输出样例:

1

解题思路:

思路简单,但要考虑一些小细节
在长和宽为1-5001的正方形区域中寻找最大的 R X R 正方形的二维前缀和。

  • 方法一:
#include <bits/stdc++.h>
using namespace std;
const int N=5100;
int a[N][N];
int main ()
{
	int n,r;cin>>n>>r;
    //因为要求二维前缀和,下标从1开始,所有点向后移动一位,即++x,++y;
	r=min(r,5001);//当r超过最大区域5001时,r就取最大值5001。
	while(n--)
	{
		int x,y,w;cin>>x>>y>>w;
		a[++x][++y]+=w;// 所给的x,y有可能会重复,所以w值要累加
	}
	for(int i=1;i<=5001;i++)
	{
		for(int j=1;j<=5001;j++)
		{
			a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
		}
	}
	int res=-0x3f3f3f3f;
	for(int i=1;i+r-1<=5001;i++)
	{
		for(int j=1;j+r-1<=5001;j++)
		{
			int x1=i+r-1,y1=j+r-1;//这个地方要注意,是i+r-1而不是i+r;
			int s=a[x1][y1]-a[i-1][y1]-a[x1][j-1]+a[i-1][j-1];
			res=max(res,s);
		}
	}
	cout<<res<<endl;
	return 0;
}
  • 方法二
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=5100;
int a[N][N];
int main ()
{
    int n,k;cin>>n>>k;
    k=min(k,5001);// 每个位置向后移动一位,所以最大值为5001
    while(n--)
    {
        int x,y,w;cin>>x>>y>>w;
        a[++x][++y]+=w;
    }
    for(int i=1;i<=5001;i++)
        for(int j=1;j<=5001;j++)
            a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
    int M=-inf;
    for(int i=k;i<=5001;i++)
    {
        for(int j=k;j<=5001;j++)
        {
            M=max(M,a[i][j]-a[i-k][j]-a[i][j-k]+a[i-k][j-k]);   
        }
    }
    cout<<M<<endl;
    return 0;
}