1. 程式人生 > >【題解】魔板—洛谷P1275

【題解】魔板—洛谷P1275

cstring 魔板 def 的確 回歸 lse stream line break

話說好久沒更博了。
最近學了好多知識懶的加進來了。
有幸認識一位大佬。
讓我有了繼續更博的興趣。
但這是一個舊的題解。
我在某谷上早就發過的。
拿過來直接用就當回歸了吧。


其實這道題有一個特別關鍵的思路。

拿著你要確定的魔板中列去枚舉要匹配的魔板的每一列。

因為列是可以交換的。

而且還有最關鍵的一個點。

如果你確定了其中有一列對應了,那麽你的魔板其實就已經固定了。行就不能變換了。

上邊這個關鍵點的確不好想,但是想通了這個題也就好解決了。

然後就可以用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;
}

完美。

【題解】魔板—洛谷P1275