洛谷 2213 [USACO14MAR]懒惰的牛The Lazy Cow_Sliver

【题解】

  每个格子可以到达的区域是一个菱形,但是我们并不能快速的求和,所以我们可以把原来的草地旋转45度,用二维前缀和快速处理菱形的区域的和。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define N 1000
 6 #define rg register
 7 using namespace std;
 8 int n,m,k,a[N][N];
 9 LL s[N][N],ans;
10 inline int read(){
11     int k=0,f=1; char c=getchar();
12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
14     return k*f;
15 }
16 int main(){
17     n=read(); k=read(); 
18     for(rg int i=1;i<=n;i++)
19         for(rg int j=1;j<=n;j++) a[n+i-j][i+j-1]=read();
20     m=n*2-1;
21 //    for(rg int i=1;i<=m;i++){
22 //        for(rg int j=1;j<=m;j++) printf("%d ",a[i][j]); puts("");
23 //    }
24     for(rg int i=1;i<=m;i++)
25         for(rg int j=1;j<=m;j++) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
26 //    for(rg int i=1;i<=m;i++){
27 //        for(rg int j=1;j<=m;j++) printf("%lld ",s[i][j]); puts("");
28 //    }
29     for(rg int i=1;i<=n;i++)
30         for(rg int j=1;j<=n;j++){
31             int x=n+i-j,y=i+j-1;
32             int c1=min(x+k,m),r1=min(y+k,m),c2=max(x-k-1,0),r2=max(y-k-1,0);
33             ans=max(ans,s[c1][r1]-s[c1][r2]-s[c2][r1]+s[c2][r2]);
34         }
35     printf("%lld
",ans);
36     return 0;
37 }
原文地址:https://www.cnblogs.com/DriverLao/p/9746712.html