二进制矩阵

二进制矩阵

题目链接

思路

根据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;
}
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值