洛谷 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\n",ans); 36 return 0; 37 }