3763. 数字矩阵

AcWing 3763. 数字矩阵

题目:

给定一个 n×m 的整数矩阵,其中第 i 行第 j 列的元素为 aij。

你可以进行任意多次如下操作:

选择矩阵中的两个相邻元素,将它们均乘以 −1。

同一个元素可以被选中多次。

你需要通过上述操作,使得矩阵中所有元素的和尽可能大。

计算并输出这个和的最大可能值。

输入格式
第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含两个整数 n,m。

接下来 n 行,每行包含 m 个整数,表示整个矩阵,其中第 i 行第 j 列的数为 aij。

输出格式
每组数据输出一行结果,表示矩阵的所有元素的最大可能和。

数据范围
1≤T≤100,
2≤n,m≤10,
−100≤aij≤100
输入样例:
2
2 2
-1 1
1 1
3 4
0 -1 -2 -3
-1 -2 -3 -4
-2 -3 -4 -5
输出样例:
2
30

思路:

本题思路:相邻两个位置可以同时乘上-1,则可以进行延伸到整个矩阵的范围,
一条路线中只有头尾位置的符号改变(变换一次),路线中的其他位置的符号不变(变换两次)
题目说可以进行任意次操作,故可以同时改变矩阵中任意两个元素的符号
题目要求经过操作后求矩阵的最大值,则可以先统计矩阵中的负数的总个数,累加矩阵中所有元素的绝对值
分为两种情况:
    1.当矩阵中的负数个数为偶数时,由于可以用时改变任意两个元素的正负,所有直接输出矩阵元素的绝对值之和即可
    2.当矩阵中的负数个数为奇数时,仅仅可以修改任意偶数个元素的正负,所有一定会留下一个负数,
      最终结果为 所有矩阵元素的绝对值之和 减去 2倍最小绝对值的差

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

int main()
{
    int n, m, i, j;
    int num[15][15] = {0};
    int T;
    cin>>T;
    while (T--)
    {
        cin>>n>>m;
        memset(num,0,sizeof(num));
        int count = 0, Min = 1e5, sum = 0;
        for (i = 0; i < n; i++)
            for (j = 0; j < m; j++)
            {
                scanf("%d",&num[i][j]);
                sum += abs(num[i][j]);
                if (Min > abs(num[i][j]))
                    Min = abs(num[i][j]);
                if (num[i][j] < 0)
                    count++;
                }
        if (count % 2)
            cout<<sum-2*Min<<endl;
        else
            cout<<sum<<endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值