[CF463C] Gargari and Bishops - 结论
Description
给定一个 (n imes n) 的国际象棋棋盘,每个格子有一个得分,你需要在棋盘上放置两个象(可以沿着对角线行走),要求不能有位置同时被两个象攻击到,而恰好能被一个象攻击到的位置可以获得格子对应的得分。求得分的最大值,以及放置象的方案。
Solution
首先,容易证明,若我们对格子黑白染色,则两个象一定放在异色的格子中。
于是我们可以处理出每条对角线的和,这样我们就可以 (O(1)) 询问将象放在一个格子中所能获得的得分。同时我们注意到,在满足上述条件的情况下,这两种方案所能获得的答案其实是独立的,因此我们只需要分别求出最大值即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e+6+5;
const int M = 1e+3+5;
const int mod1 = 1e+9+7;
const int mod2 = 998244353;
#define dbg(x) cerr<<#x<<":"<<x<<endl
signed main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
vector<vector<int>> a(n+2,vector<int>(n+2));
vector <int> x(2*n+2), y(2*n+2);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
x[i+j]+=a[i][j];
y[i-j+n]+=a[i][j];
}
}
vector <vector<int>> ans(2, {0,0,0});
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int val=(x[i+j]+y[i-j+n]-a[i][j]);
vector <int> tmp = {val,i,j};
ans[(i+j)&1]=max(ans[(i+j)&1],tmp);
}
}
cout<<ans[0][0]+ans[1][0]<<endl;
cout<<ans[0][1]<<" "<<ans[0][2]<<" "<<ans[1][1]<<" "<<ans[1][2]<<endl;
return 0;
}