zoukankan      html  css  js  c++  java
  • luogu P1275 魔板 题解

    题面
    题意:给你两个n×m的01矩阵,每次可以对其中一个矩阵进行交换两列,或者反转某一行(0变1,1变0)的 操作,问两个矩阵是否能互相转化。

    首先我们只考虑对第一个矩阵进行操作,让它变成第二个矩阵。
    我们考虑无论第一个矩阵如何变换,最终都需要有一列变得和第二个矩阵的第一列一样,而如果我们强制某一列变得和第二个矩阵的第一列一样的话,那么所有行上的异或操作的状态就确定了,这样我们就只需要将剩下的m-1列进行匹配就可以了。
    所以我们枚举每一列与第二个矩阵的第一列匹配,将不同的行全部反转,然后检查一下这m列能不能互相匹配。

    代码(另一种做法,将两个矩阵都变成子典序最小的状态,然后判断是否相同):

    #include<bits/stdc++.h>
    using namespace std;
    #define N 107
    char g[N][N];
    int n,m;
    void swp(int x,int y)
    {
    	for(int i=1;i<=n;i++)
    		swap(g[i][x],g[i][y]);
    }
    void chg(int x)
    {
    	for(int i=1;i<=m;i++)
    		g[x][i]^=1;
    }
    string s[N];
    string solve()
    {
    	string ret="";
    	for(int o=1;o<=m;o++)
    	{
    		swp(o,1);
    		for(int i=1;i<=n;i++)
    			if(g[i][1]=='1')chg(i);
    		for(int i=2;i<=m;i++)
    		{
    			s[i]="";
    			for(int j=1;j<=n;j++)
    				s[i]+=g[j][i];
    		}
    		sort(s+2,s+m+1);
    		string t="";
    		for(int i=2;i<=m;i++)
    			t+=s[i];
    		if(o==1)ret=t;
    		else ret=min(ret,t);
    	}
    	return ret;
    }
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=m;j++)
    				scanf("%s",&g[i][j]);
    		string s1=solve();
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=m;j++)
    				scanf("%s",&g[i][j]);
    		string s2=solve();
    		if(s1==s2)printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    JDBC 复习4 批量执行SQL
    JDBC 复习3 存取Oracle大数据 clob blob
    Oracle复习
    Linux命令(1)grep
    JDBC 复习2 存取mysql 大数据
    JDBC 复习1 DBUtil
    php 环境搭建问题
    Windows 批处理 bat 开启 WiFi 菜单选项 设置ID PWD
    Bat 批处理启动和停止Oracle 服务
    docker 学习1 WSL docker ,Windows docker
  • 原文地址:https://www.cnblogs.com/lishuyu2003/p/12142459.html
Copyright © 2011-2022 走看看