XUANMING'S JOURNAL屏幕在深夜微微发亮,我心在远方。
← 回到笔记
FIELD NOTES

CF1447B

题意很清晰,首先关注翻转的性质,有一个结论:

实际上每次可以翻转任意两个数。

为什么呢?考虑比如我们要翻转$(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;
}

输入关键词,搜索全部笔记。