训练3.29(CF 463c Gargari and Bishops)

题目速递:http://codeforces.com/problemset/problem/463/C

题意:在一个n*n矩阵中,每个小方格中都有一个值。记某方格主对角线副对角线经过的所有方格为他的区域。规定在某个小方格放置bishop时,将会收获该方格区域上方格的值的和,这个和记作该方格的收益。现要放置两个bishops,且放置的两个位置的“区域”不可重叠。问如何放置能得到最大收益。

题解:画一下图会发现,同一条主对角线上的点的坐标(x,y),其x-y为定值;同一条副对角线上的则x+y为定值。
x1[i],x2[i],分别表示坐标差为i对角线上的方格的值之和、坐标和为i对角线上的方格的值之和。于是每个小方格该对谁有贡献就很清楚,遍历一遍加进去就ok。
(x1的下标这里暂且写作i,为了方便理解。然鹅因为是下标,还是取为正数比较好,所以代码里的下标会再加个n)

接下来就是两个bishops如何放置不会冲突的问题了。也是画一画能发现的,当x+y为偶数时,他的区域只会和x+y为偶数的点的区域重叠,和那些x+y为奇数的方格的区域则不会重叠的。x+y为奇数亦然。【这是个n*n矩阵

所以想要取不会冲突的两个位置,就将点分成两个集合,各自找最大值就行。

具体操作见代码

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const int maxn=3e3+33;
ll a[maxn][maxn];
ll x1[3*maxn],x2[3*maxn];
ll n;
int main(){
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++){
		for(ll j=1;j<=n;j++){
			scanf("%lld",&a[i][j]);
			x1[i-j+n]+=a[i][j];
			x2[i+j]+=a[i][j];
		}
	}
	ll x_1,y_1,x_2,y_2;
	ll max1,max2;
	x_1=y_1=x_2=1;y_2=2; 
	max1=max2=0;
	for(ll i=1;i<=n;i++){
		for(ll j=1;j<=n;j++){
			ll tmp=x1[i-j+n]+x2[i+j]-a[i][j];
			if(tmp>max1&&(i+j)%2==1){
				max1=tmp;x_1=i;y_1=j;
			}else if(tmp>max2&&(i+j)%2==0){
				max2=tmp;x_2=i;y_2=j;
			}
		}
	}
	printf("%lld\n",max1+max2);
	printf("%lld %lld %lld %lld\n",x_1,y_1,x_2,y_2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值