题意很清晰,首先关注翻转的性质,有一个结论:
实际上每次可以翻转任意两个数。
为什么呢?考虑比如我们要翻转$(x_1,y_1),(x_2,y_2)(x_1\le x_2,y_1\le y_2)$,我们可以一路翻转$(x_1,y_1),(x_1,y_1+1)$,再翻转$(x_1,y_1+1),(x_1,y_1+2)$,一直到$(x_1,y_2-1),(x_1,y_2)$。同理我们可以一路翻转到$(x_2,y_2)$,可以发现,除了两个端点$(x_1,y_1),(x_2,y_2)$,一路上所有的点都被翻转了两次翻回来了,所以就实现了翻转任意两个数。
接下来就很简单了。首先如果负数是偶数个,那么可以直接翻转,否则必然要剩下一个,我们就选取矩形中绝对值最小的数作为剩下的负数就可以了。
代码:
#include <cstdio>
#include <iostream>
using namespace std;
const int maxn=105;
int n,m;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int cnt=0,ans=0,mi=101;
scanf("%d%d",&n,&m);
for(int i=1,x;i<=n;++i)
for(int j=1;j<=m;++j)
{
scanf("%d",&x);
if(x<0) x=-x,++cnt;
mi=min(mi,x);ans+=x;
}
if(cnt&1) printf("%d\n",ans-mi*2);
else printf("%d\n",ans);
}
return 0;
}