本题出自cf中,我第一眼看到这一题,我脑子里想完了,情况也太多了,后来看了y总的视频发现这道题就是:让你判断你输入的数中有几个负数,以及去找出其中绝对值最小的数,因为两个负数总可以通过一条折线连接起来,去改变这两个负数的值而保持这条折线中的其它数的符号不变(因为我们可以发现这条折线中的其他数总会改变两次符号,也即符号不变),以此为思路,我们解题代码如下。
给定一个 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
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m,k,h=100,sumf=0,sum=0;
cin>>n>>m;
for(int i=0;i<n*m;i++)
{
cin>>k;
if(k<0) sumf++;//统计负数的个数
sum+=abs(k);//统计所有数的绝对值的和
h=min(h,abs(k));
}
if(sumf%2) cout<<sum-2*h<<endl;//偶数个负数的情况应当减去相应的最小值的二倍
else cout<<sum<<endl;
}
}