6360. 【NOIP2019模拟2019.9.18】最大菱形和(rhombus)

63 篇文章 0 订阅

Description

Input

Output

Sample Input

5 5 2 0
1 5 7 3 -4
2 0 -9 8 3
9 0 7 8 2
-4 5 -7 1 4
5 8 7 0 6 

Sample Output

26

Data Constraint

Solution

法一:

        维护一个矩形的和以及四个角上多的和,用总的减去多的即为菱形。但空间有点悬,需要滚动一下。

法二:

        维护每一行的前缀和,以及向斜上方(左上和右上)的前缀和。对于每一行,先求出以(i,j)为中心的菱形,然后当转移到(i,j+1)时,变化的只有斜边,也就是减掉原菱形左上和左下的斜边,加上现菱形右上和右下的斜边即可。

法三:

        将整个矩形转45度角,然后枚举一个有数的点,接着就相当于矩形求和了,直接上二维前缀和。

Code1

#include<cstdio>
#include<cstring>
#include<algorithm>
#define I int
#define ll long long
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define N 3005

using namespace std;
I rd(I &x){
	x=0;I w=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	x*=w;
}
I n,m,h,ty,Se,A,B,C,M,a[N][N];
ll g[N][N],s[N][N],mx[2];
ll r1[N][N],r2[N][N],l1[N][N],l2[N][N],ans;
struct Data{
	ll Se,A,B,C,M;
	ll R(ll &x){
		x=0;ll w=1;char c=getchar();
		while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
		while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
		x*=w;
	}
	ll Random(){
		Se=(Se*A+B*(++C))%M;
		return Se;
	}
	I Random_int(){
		I tmp=Random();
		if(Random()&1)tmp*=-1;
		return tmp;
	}
	void MAKE(){
		R(Se),R(A),R(B),R(C),R(M);
		F(i,1,n)
			F(j,1,m) a[i][j]=Random_int();
	}
}init;
I main(){
	freopen("rhombus.in","r",stdin);
	freopen("rhombus.out","w",stdout);
	rd(n),rd(m),rd(h),rd(ty);--h;
	if(ty){init.MAKE();}
	else{
		F(i,1,n)
			F(j,1,m) rd(a[i][j]);
	}
	F(i,1,n)
		F(j,1,m){
			g[i][j]=g[i-1][j]+a[i][j];
			s[i][j]=s[i-1][j+1]+a[i][j];
		}
	F(i,1,n-h+1){
		F(j,1,h) l1[i][h]+=g[i+h-j][j]-g[i-1][j];
		F(j,h+1,m){
			l1[i][j]=l1[i][j-1]-g[i+h-1][j-h]+g[i-1][j-h]+s[i+h-1][j-h+1]-s[i-1][j+1];
		}
	}
	F(i,h,n){
		F(j,1,h) r2[i][1]+=g[i][j]-g[i-j][j];
		F(j,2,m-h+1){
			r2[i][j]=r2[i][j-1]+g[i][j+h-1]-g[i-h][j+h-1]-s[i][j-1]+s[i-h][j+h-1];
		}
	}
	mem(s,0);
	F(i,1,n)
		F(j,1,m) s[i][j]=s[i-1][j-1]+a[i][j];
	F(i,h,n){
		F(j,1,h) l2[i][h]+=g[i][j]-g[i-h+j-1][j];
		F(j,h+1,m){
			l2[i][j]=l2[i][j-1]-g[i][j-h]+g[i-h][j-h]+s[i][j]-s[i-h][j-h];
		}
	}
	F(i,1,n-h+1){
		F(j,1,h) r1[i][1]+=g[i+j-1][j]-g[i-1][j];
		F(j,2,m-h+1){
			r1[i][j]=r1[i][j-1]+g[i+h-1][j+h-1]-g[i-1][j+h-1]-s[i+h-1][j+h-2]+s[i-1][j-2];
		}
	}
	I H=h*2+1;
	F(i,1,n-H+1){
		mx[1]=mx[0]=0;
		F(j,1,H) mx[1]+=g[i+H-1][j]-g[i-1][j];
		I x=h+i,y=h+1;
		if(x-h>0&&y-h>0&&x+h<=n&&y+h<=m) ans=max(ans,mx[1]-l1[x-h][y-1]-l2[x+h][y-1]-r1[x-h][y+1]-r2[x+h][y+1]);
		I p=0;
		F(j,2,m-H+1){
			mx[p]=mx[1-p]-g[i+H-1][j-1]+g[i-1][j-1]+g[i+H-1][j+H-1]-g[i-1][j+H-1];
			I x=i+h,y=j+h;
			if(x-h>0&&y-h>0&&x+h<=n&&y+h<=m) ans=max(ans,mx[p]-l1[x-h][y-1]-l2[x+h][y-1]-r1[x-h][y+1]-r2[x+h][y+1]);
			p=1-p;
		}
	}
	/*F(i,1,n-H+1){
		F(j,1,H) mx[i][1]+=g[i+H-1][j]-g[i-1][j];
		F(j,2,m-H+1){
			mx[i][j]=mx[i][j-1]-g[i+H-1][j-1]+g[i-1][j-1]+g[i+H-1][j+H-1]-g[i-1][j+H-1];
		}
	}
	F(i,h+1,n-h){
		F(j,h+1,m-h){
			ans=max(ans,mx[i-h][j-h]-l1[i-h][j-1]-l2[i+h][j-1]-r1[i-h][j+1]-r2[i+h][j+1]);
		}
	}*/
	printf("%lld\n",ans);
	return 0;
}

Code2

#include<cstdio>
#include<cstring>
#include<algorithm>
#define I int
#define ll long long
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define N 3005
using namespace std;
ll R(ll &x){
	x=0;I w=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	x*=w;
}
ll n,m,h,ty,Se,A,B,C,M,a[N][N];
ll t[N][N],s[N][N],f[N][N],ans,sum;
struct Data{
	ll Se,A,B,C,M;
	ll Random(){return Se=(Se*A+B*(++C))%M;}
	I Random_int(){I tmp=Random();if(Random()&1)tmp*=-1;return tmp;}
	void MAKE(){
		R(Se),R(A),R(B),R(C),R(M);
		F(i,1,n)
			F(j,1,m) a[i][j]=Random_int();
	}
}init;
I main(){
	freopen("rhombus.in","r",stdin);
	freopen("rhombus.out","w",stdout);
	R(n),R(m),R(h),R(ty);--h;
	if(ty){init.MAKE();}
	else{
		F(i,1,n)
			F(j,1,m) R(a[i][j]);
	}
	F(i,1,n)
		F(j,1,m){
			f[i][j]=f[i][j-1]+a[i][j];
			s[i][j]=s[i-1][j+1]+a[i][j];
			t[i][j]=t[i-1][j-1]+a[i][j];
		}
	F(i,h+1,n-h){
		sum=f[i][2*h+1];
		F(j,1,h) sum+=f[i-j][2*h+1-j]-f[i-j][j]+f[i+j][2*h+1-j]-f[i+j][j];
		ans=max(ans,sum);
		F(j,h+2,m-h){
			sum=sum+a[i][j+h]-a[i][j-1-h]-s[i-1][j-h]+s[i-h-1][j]+s[i+h][j]-s[i][j+h]-t[i+h][j-1]+t[i][j-h-1]+t[i-1][j+h-1]-t[i-h-1][j-1];
			ans=max(ans,sum);
		}
	}
	printf("%lld\n",ans);
	return 0;
}

Code3

#include<cstdio>
#include<cstring>
#include<algorithm>
#define I int
#define ll long long
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define N 3005
using namespace std;
ll R(ll &x){
	x=0;I w=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	x*=w;
}
ll n,m,h,ty,Se,A,B,C,M,a[N][N];
ll f[N*2][N*2],ans,sum;
struct Data{
	ll Se,A,B,C,M;
	ll Random(){return Se=(Se*A+B*(++C))%M;}
	I Random_int(){I tmp=Random();if(Random()&1)tmp*=-1;return tmp;}
	void MAKE(){
		R(Se),R(A),R(B),R(C),R(M);
		F(i,1,n)
			F(j,1,m) a[i][j]=Random_int();
	}
}init;
I main(){
	freopen("rhombus.in","r",stdin);
	freopen("rhombus.out","w",stdout);
	R(n),R(m),R(h),R(ty);--h;
	if(ty){init.MAKE();}
	else{
		F(i,1,n)
			F(j,1,m) R(a[i][j]);
	}
	F(i,1,n){
		F(j,1,m) f[i+j-1][n-i+1+j-1]=a[i][j];
	}
	F(i,1,n+m-1){
		F(j,1,n+m-1) f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
	}	
	F(i,h+1,n-h){
		F(j,h+1,m-h){
			I x=i+j-1,y=n-i+1+j-1;
			ans=max(ans,f[x+h][y+h]-f[x-h-1][y+h]-f[x+h][y-h-1]+f[x-h-1][y-h-1]);
		}
	}
	printf("%lld\n",ans);
	return 0;
}


作者:zsjzliziyang 
QQ:1634151125 
转载及修改请注明 
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/102293536

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值