题目:
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.
4 1 1 1 1 2 1 1 0 1 1 1 0 1 0 0 1
12 2 2 3 2
题意分析:
给你一个n*n的格子,每个格子都有一个数值!将两仅仅bishops放在某一个格子上,每个bishop能够攻击对角线上的格子(主对角线和者斜对角线),然后会获得格子上的数值(仅仅能获取一次)。要求输出两个bishops获取的最大值以及它们所在的位置!
思路:暴力吧,首先我们都知道每一条主对角线上的横纵坐标的和同样,每一条副对角线上的横纵坐标的差同样!那么我们在输入的时候就能够将全部对角线上的数值之和求出来了。 最后我们发现假设要获得最大值,那么另一条就是两个bishops所在的对角线不能相交在同一个格子上。仅仅要满足两个bishops的哼纵坐标之和互为奇偶即可了。在全部格子中找到横纵坐标之和为奇数而且获得对角线上数值最大的格子和横纵坐标之和为偶数而且获得对角线上数值最大的格子。二者最大获得值相加就是终于的答案了。 比赛没什么好的思路,如今补上。非常不错的题目
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define N 2005 using namespace std; typedef long long LL; int num[N][N]; LL sumN[N*2], sumM[N*2]; int n; int main() { while(scanf("%d", &n)!=EOF) { memset(sumN, 0, sizeof(sumN)); memset(sumM, 0, sizeof(sumM)); for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) { scanf("%d", &num[i][j]); sumN[i+j]+=num[i][j];//横纵坐标之和为i+j的对角线的数值和 sumM[i-j+n]+=num[i][j];//横纵坐标之差为i-j的对角线的数值和 } LL max1=-1, max2=-1, s; int x1, x2, y1, y2; for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) { if((i+j)&1) { if(max1<(s=sumN[i+j]+sumM[i-j+n]-num[i][j])) { max1=s;//横纵坐标之和为奇数而且获得对角线上数值最大的格子 x1=i; y1=j; } } else { if(max2<(s=sumN[i+j]+sumM[i-j+n]-num[i][j])) { max2=s;//横纵坐标之和为偶数而且获得对角线上数值最大的格子 x2=i; y2=j; } } } printf("%lld ",max1+max2); printf("%d %d %d %d ", x1, y1, x2, y2); } return 0; }