现在的位置: 首页 > 综合 > 正文

CodeForce 463C Gargari and Bishops(贪心+暴力)

2017年07月14日 ⁄ 综合 ⁄ 共 2189字 ⁄ 字号 评论关闭
time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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).

Input

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.

Output

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.

Sample test(s)
input
4
1 1 1 1
2 1 1 0
1 1 1 0
1 0 0 1
output
12
2 2 3 2
题意:给出一个n*n的棋盘,每个方格中有一个非负整数,在棋盘中放两个象,使得这两个象既不会互相攻击,攻击范围也不能有重合,并且在这两个象攻击范围内的格子中的值的总和最大,输出总和和两个象的位置坐标。如果一个格子和象在一条对角线上,则这个格子就在这个象的攻击范围内。
分析:简单分析可以得出:位于同一条主对角线上元素Map[i][j]满足i-j相同,位于同一条副对角线上的元素Map[i][j]满足i+j相同。如果两个象不会互相攻击,且攻击范围没有重合,那么这两个象的坐标x1+y1和x2+y2的奇偶性一定不同。所以我们只需预处理出每条对角线上的元素之和,然后更新即可。具体见代码。
#include<cstdio>
#include<cstring>
const int N = 2005;
typedef long long LL;
LL Map[N][N]; //棋盘
LL L[N*2]; //副对角线元素之和
LL R[N*2]; //主对角线元素之和
int main()
{
    int n;
    while(~scanf("%d",&n)) {
        memset(L, 0, sizeof(L));
        memset(R, 0, sizeof(R));
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                scanf("%I64d",&Map[i][j]);
                L[i+j] += Map[i][j]; //同一条副对角线i+j相同
                R[i-j+n] += Map[i][j]; //同一条主对角线i-j相同
            }
        }
        int x1 = 1, x2 = 1, y1 = 1, y2 = 2;
        LL max1 = 0, max2 = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                LL tmp = L[i+j] + R[i-j+n] - Map[i][j];
                if((i+j) % 2 == 0 && tmp > max1) {
                    max1 = tmp;
                    x1 = i;
                    y1 = j;
                }
                if((i + j) % 2 == 1 && tmp > max2) {
                    max2 = tmp;
                    x2 = i;
                    y2 = j;
                }
            }
        }
        printf("%I64d\n", max1 + max2);
        printf("%d %d %d %d\n", x1, y1, x2, y2);
    }
    return 0;
}

抱歉!评论已关闭.