二进制矩阵
思路
根据y总的结论,任意一个数为1时,我们都可以通过三次操作在不影响其他点的情况下,将其转换为0,即如图所示的方法:
而操作数的限制为 3nm3nm, 所以就算把每一个点都进行三次操作都是满足这个限制的
显然第一问的答案输出给定矩阵中1的个数乘以3即可。
#include <iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 110;
int n, m;
char s[N][N];
void print(int i, int j,int k) { //左上0,右上1,右下2,左下3
if(!k)printf("%d %d %d %d %d %d\n", i, j, i+1, j , i , j+1);
else if(k==1)printf("%d %d %d %d %d %d\n", i, j-1, i , j, i + 1, j );
else if(k==2)printf("%d %d %d %d %d %d\n", i-1, j, i, j , i , j -1);
else printf("%d %d %d %d %d %d\n", i - 1, j, i, j , i , j + 1);
}
int main() {
int T;
cin >> T;
while (T -- ) {
int sum = 0;
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) {
cin>>s[i] + 1;
for (int j = 1; j <= m; j ++ )
if (s[i][j] == '1') sum += 3;
}
cout <<sum<< endl;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
if (s[i][j] == '1') {
if (i<n&&j<m)
print(i, j,0),print(i, j+1,1), print(i+1, j,3);
else if (i==n&&j==m)
print(i,j,2),print(i - 1, j,1), print(i , j-1,3);
else if (i == n )
print(i , j,3), print(i - 1, j ,0),print(i , j+1 ,2);
else
print(i, j ,1),print(i, j-1 ,0),print(i+1, j ,2);
}
}
return 0;
}
数字矩阵
思路
如一个矩阵
1 -2 3
1 2 3
1 2 3
我们想让(1,2)的-2变号成2
则可以通过将(1,1)和(1,2)一起变号成为-1,2
然后再将(1,1)和(2,1)一起变号成1,-1
这样就完成了将(1,1)不变,而让(1,2)和(2,1)变号
所以说变号不仅是能将其相领的元素一起变号,还可以扩充到左上左下右上右下四个方向
再推下去 每对同时变号的元素可以处于矩阵的任何两个位置
所以只要统计矩阵中有多少个负号,如果负号的数量是奇数,就证明必须有一个元素是负号,让绝对值最小的是负号就行
如果是偶数,就证明所有数都可以变成正号
#include<iostream>
#include<algorithm>
using namespace std;
int a[15][15]={0};
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m,sum=0,count=0,Min=1e9;
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
cin>>a[i][j];
sum+=abs(a[i][j]);
if(a[i][j]<0)count++;
Min=min(Min,abs(a[i][j]));
}
sum-=Min*(count%2)*2;
cout<<sum<<endl;
}
return 0;
}