【題解】魔板—洛谷P1275
阿新 • • 發佈:2019-02-24
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