1931. 懒惰的奶牛[s](lazy_silver)
题目描述
夏天到了,奶牛贝里斯又开始变得懒惰起来。他想要站在一个地方,然后吃掉一定范围内的所有青草。贝里斯所在的田地可以描述为一个NN的方阵,对于方阵中的第r行和第c列上的数字G(r,c),表示这个小方格中青草的数量。贝里斯会在方阵中选择一个初始位置(小方格),然后以这个位置为起点经过的步数不超过K的地方的青草都将被贝里斯吃掉。每走一步,就是走到相邻(上下左右直接相邻)的其中一个小方格中去。例如,有一个方阵如图所示,贝里斯的初始位置是(3,3),有(B)标示的地方。
如果K=2,那么贝里斯只能走到号所标示的地方。如果初始的位置可以选择的话,请帮助贝里斯计算他最多能吃到的青草的数量。
输入
第一行是两个正整数N和K。
接下里N行,每行N个整数,表示方阵。
输出
贝里斯最多能吃到的青草的数量。
样例输入
5 2
50 5 25 6 17
14 3 2 7 21
99 10 1 2 80
8 7 5 23 11
10 0 78 1 9
样例输出
342
数据范围限制
1<=N<=400,0<=G(r,c)<=1000,0<=K<=2*N。
提示
样例中,如果贝里斯的初始位置是(3,3)的话,他能吃到最多的青草数量是342。
思路:
这道题我们可以看成是一个多层的区间和,如图:
唯一考虑一下如何算出每一行相对应的区间左右点。就等于能走的步数减去当前行的与奶牛所在行的的差值,剩下的步数不就是了吗?
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
int n,k,a[410][410],qzh[410][410],maxn;
int main()
{
fre(lazy_silver);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]),qzh[i][j]=qzh[i][j-1]+a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int temp=0;
for(int x=i-k;x<=i+k;x++)
{
if(x<0) x=1;
if(x>n) break;
int l=max(j-k+abs(i-x)-1,0);
int r=min(j+k-abs(i-x),n);
temp+=qzh[x][r]-qzh[x][l];
}
maxn=max(maxn,temp);
}
printf("%d",maxn);
return 0;
}