Div4 1676 D 矩阵对角线性质

D. X-Sum

Timur’s grandfather gifted him a chessboard to practice his chess skills. This chessboard is a grid a a a with n n n rows and m m m columns with each cell having a non-negative integer written on it.

Timur’s challenge is to place a bishop on the board such that the sum of all cells attacked by the bishop is maximal. The bishop attacks in all directions diagonally, and there is no limit to the distance which the bishop can attack. Note that the cell on which the bishop is placed is also considered attacked. Help him find the maximal sum he can get.

Input

The first line of the input contains a single integer t t t ( 1 ≤ t ≤ 1000 1 \le t \le 1000 1t1000) — the number of test cases. The description of test cases follows.

The first line of each test case contains the integers n n n and m m m ( 1 ≤ n ≤ 200 1 \le n \le 200 1n200, 1 ≤ m ≤ 200 1 \leq m \leq 200 1m200).

The following n n n lines contain m m m integers each, the j j j-th element of the i i i-th line a i j a_{ij} aij is the number written in the j j j-th cell of the i i i-th row ( 0 ≤ a i j ≤ 1 0 6 ) (0\leq a_{ij} \leq 10^6) (0aij106)

It is guaranteed that the sum of n ⋅ m n\cdot m nm over all test cases does not exceed 4 ⋅ 1 0 4 4\cdot10^4 4104.

Output

For each test case output a single integer, the maximum sum over all possible placements of the bishop.

Example

input

4
4 4
1 2 2 1
2 4 2 4
2 2 3 1
2 4 2 4
2 1
1
0
3 3
1 1 1
1 1 1
1 1 1
3 3
0 1 1
1 0 1
1 1 0

output

20
1
5
3

Note

For the first test case here the best sum is achieved by the bishop being in this position:

简述题意

题目要求我们在 n ∗ m n * m nm的一个矩阵中确定一个点

以该点为中心向两条对角线扩深,找到覆盖方格和的最大值

正如题目在 ( 3 , 3 ) (3,3) (3,3)点放置棋子,对应的值为 1 + 4 + 3 + 4 + 4 + 4 1 + 4 + 3 + 4 + 4 + 4 1+4+3+4+4+4

解题思路

初始想法

n , m ≤ 200 n,m \leq 200 n,m200 给出的矩阵很小,我们优先考虑暴力做法

我们遍历每一个点分别向四个方向构建一个双指针for循环,统计好每一个方向的值后,加上中心点

最后将ans取最大值,也就是我们的结果

简单看一下时间复杂度两层for循环 O ( n ∗ m ) = O ( n 2 ) O(n * m) = O(n ^ 2) O(nm)=O(n2),四个方向 O ( n ) O(n) O(n),总共大概 O ( n 3 ) = 8000000 O(n ^ 3) = 8000000 O(n3)=8000000,应该还是可以过的

四个for循环,想想就恶心,懒得写

这里我们可以考虑矩形中对角线的性质

  • 一条对角线对应 i + j i + j i+j相等
  • 另一条对角线对应 i − j i - j ij相等

开两个数组或者说开两个Map都是可以的,用来统计对角线的和

但是注意一定不要开成一个数组了,万一出现了 i = 3 , j = 1 i = 3,j = 1 i=3,j=1 i = 1 , j = 1 i = 1,j = 1 i=1,j=1

明明两个都不在一个对角线上,你却将他们算在了对角线上

写的时候没想,在这卡了3次,下一题E题(也是贪心)一次过,这题3次唉。。。。

最精彩的Code环节

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define str string
#define all(x) begin(x),end(x)
#define pb(x) push_back(x)
const int N = 210;
int a[N][N];
map<int,int> m1,m2;
inline void solve() {
    m1.clear(),m2.clear();
    memset(a,0,sizeof(a));
    int n,m,ans = 0; cin >> n >> m;
    for(int i = 1;i <= n;i++) {
        for(int j = 1;j <= m;j++) {
            cin >> a[i][j];
        }
    }

    for(int i = 1;i <= n;i++) {
        for(int j = 1;j <= m;j++) {
            m1[i + j] += a[i][j]; m2[i - j] += a[i][j];
            
        }
    }

    for(int i = 1;i <= n;i++) {
        for(int j = 1;j <= m;j++) {
            ans = max(ans,m1[i + j] + m2[i - j] - a[i][j]);
        }
    }

    cout << ans  << endl;
    
}

int main(){
    // freopen("input.txt","r",stdin);
    int t; cin >> t;
    while(t--) solve();

    // solve();

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值