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;
}