【题解】魔板—洛谷P1275。

话说好久没更博了。
最近学了好多知识懒的加进来了。
有幸认识一位大佬。
让我有了继续更博的兴趣。
但这是一个旧的题解。
我在某谷上早就发过的。
拿过来直接用就当回归了吧。


其实这道题有一个特别关键的思路。

拿着你要确定的魔板中列去枚举要匹配的魔板的每一列。

因为列是可以交换的。
而且还有最关键的一个点。

如果你确定了其中有一列对应了,那么你的魔板其实就已经固定了。行就不能变换了。

上边这个关键点的确不好想,但是想通了这个题也就好解决了。

然后就可以用map进行对应开始查询。

如果手里的魔板的数和要确定了一一对应了就YES了。

然后你手里的魔板和需要对应的魔板对应成功就可以输出YES了。

要记着在每次枚举的时候clear一次。

具体看下面代码。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<map> 
#define rg register
#define int long long 
using namespace std;
inline int read(){
    rg int s=0,f=0;
    rg char ch=getchar();
    while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
    while(isdigit(ch)) s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
    return f?-s:s;
}
int n,m,k;
const int MAX=115;
int a1[MAX][MAX],a2[MAX][MAX],vis[MAX];
string S;
map<string,int>hsh;
void init(){
    n=read(),m=read();
    for(rg int i=1;i<=n;++i){
        for(rg int j=1;j<=m;++j){
            a1[i][j]=read();
        }
    }
    for(rg int i=1;i<=n;++i){
        for(rg int j=1;j<=m;++j){
            a2[i][j]=read();
        }
    }
}
signed main(){
    k=read();
    ++k;
    while(--k){
        bool flag=0;
        init();//初始化。
        for(rg int i=1;i<=m;++i){
            hsh.clear();//每次都要清空。
            for(rg int j=1;j<=n;++j){
                vis[j]=(a1[j][1]==a2[j][i])?0:1;
            }//枚举是否能够对应。
            for(rg int j=1;j<=n;++j){
                for(rg int k=1;k<=m;++k){
                    a1[j][k]^=vis[j];
                }
            }//对应就可以^1(代表翻转过了)。
            for(rg int j=1;j<=m;++j){
                string s=S;
                for(rg int k=1;k<=n;++k){
                    s+=(char)(a1[k][j]+'0');
                }
                ++hsh[s];
            }//转换成字符串。
            for(rg int j=1;j<=n;++j){
                for(rg int k=1;k<=m;++k){
                    a1[j][k]^=vis[j];
                }
            }//还原
            for(rg int j=1;j<=m;++j){
                string s=S;
                for(rg int k=1;k<=n;++k){
                    s+=(char)(a2[k][j]+'0');
                }
                if(!hsh[s]) break;//这里没被改过就跳过。
                --hsh[s];
                if(j==m) flag=1;
            }
        }
        if(flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

完美。

转载于:https://www.cnblogs.com/Sinyess/p/10427448.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值