题目详情
输入样例:
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;
}