Gargari is jealous that his friend Caisa won the game from the previous problem. He wants to prove that he is a genius.
He has a n × n chessboard. Each cell of the chessboard has a number written on it. Gargari wants to place two bishops on the chessboard in such a way that there is no cell that is attacked by both of them. Consider a cell with number x written on it, if this cell is attacked by one of the bishops Gargari will get x dollars for it. Tell Gargari, how to place bishops on the chessboard to get maximum amount of money.
We assume a cell is attacked by a bishop, if the cell is located on the same diagonal with the bishop (the cell, where the bishop is, also considered attacked by it).
The first line contains a single integer n (2 ≤ n ≤ 2000). Each of the next n lines contains n integers aij (0 ≤ aij ≤ 109) — description of the chessboard.
On the first line print the maximal number of dollars Gargari will get. On the next line print four integers: x1, y1, x2, y2 (1 ≤ x1, y1, x2, y2 ≤ n), where xi is the number of the row where the i-th bishop should be placed, yi is the number of the column where the i-th bishop should be placed. Consider rows are numbered from 1 to n from top to bottom, and columns are numbered from 1 to n from left to right.
If there are several optimal solutions, you can print any of them.
题意:
就是在一个棋盘上摆放两个国际象棋中的象,象能够攻击到与它在同一条斜线上的对象。
现在给你一个N*N的棋盘,其中每个格子都有个值,代表攻击后的得分。
要求你求出摆放两个象所能获得的最大的分数。并且这两个象的攻击范围不能有重合。
分析:
直接看代码的注释吧。
可以注意到:
同一条从左上到右下的斜线上的元素满足 i-j 相同。
同一条从左下到右上的斜线上的元素满足 i+j 相同。
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
typedef long long LL;
const int N = 2e3 + 10;
int mat[N][N];
LL L[3*N]; //从左下到右上的斜线上的元素和
LL R[3*N]; //从右下到左上的斜线上的元素和
LL G[N][N]; //在改点摆放棋子所能获得的分数
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++) //读入元素,预处理L,R
for(int j=0; j<n; j++){
scanf("%d",&mat[i][j]);
L[i+j]+=mat[i][j];
R[i-j+n]+=mat[i][j];
}
for(int i=0;i<n;i++){ //计算G[][]
for(int j=0;j<n;j++){
G[i][j]=L[i+j]+R[i-j+n]-mat[i][j];
}
}
int x1,x2,y1,y2;
x1=x2=y1=y2=0;
for(int i=0;i<n;i++){ //贪心求第一个棋子的摆放位置
for(int j=0;j<n;j++){
if(G[x1][y1]<=G[i][j])
x1=i,y1=j;
}
}
for(int i=0;i<n;i++){ //求第二个棋子摆放的位置
for(int j=0;j<n;j++){
if((x1+y1)%2==(i+j)%2) //两个棋子不能有重合的攻击范围
continue;
if(G[x2][y2]<=G[i][j])
x2=i,y2=j;
}
}
LL sum=G[x1][y1]+G[x2][y2];
printf("%I64d\n",sum);
printf("%d %d %d %d\n",x1+1,y1+1,x2+1,y2+1);
return 0;
}