BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏
原理很简单
只要确定第一行是否翻转就可以确定以后的行是否翻转
但是最后对拍后才过了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; inline int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline int count(int x){ int res=0; while(x) res+=(x&1),x>>=1; return res; } int m,n,ans,sum; int a[16]; inline void pri(int x){ for(int i=1;i<=n;i++) printf("%d ",x&1),x>>=1; puts(""); } inline bool ok(int x){ int ex=0,cnt=0; for(int i=1;i<=m;i++){ int b=x;cnt+=count(x); x=x^(x<<1)^(x>>1)^a[i]^ex,x%=(1<<n); ex=b; } if(x) return 0; if(cnt>=sum) return 0; sum=cnt; return 1; } inline void print(int x){ int ex=0; for(int i=1;i<=m;i++){ pri(x);int b=x; x=x^(x<<1)^(x>>1)^a[i]^ex,x%=(1<<n); ex=b; } } inline int fan(int x){ int res=0; for(int i=1;i<=n;i++) res=(res<<1)+(x&1),x>>=1; return res; } int main(){ m=read(),n=read(); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) a[i]+=(read()<<(j-1)); ans=-1;sum=0x3f3f3f3f; for(int i=0;i<(1<<n);i++) if(ok(fan(i))) ans=fan(i); if(ans==-1) puts("IMPOSSIBLE"); else print(ans); return 0; }