2965 The Pilots Brothers' refrigerator
問題概要
冷蔵庫には4x4個の取っ手がついており、全てが開の状態にならないと開かない。
一つの取っ手の状態を反転させる(開→閉およびその逆)と、その取っ手と同じ行および列にある取っ手全ての状態が反転する。
取っ手の初期状態が与えられるとき、最短の手順で冷蔵庫のドアを開ける手順を出力せよ。
それが複数ある場合はどれを出力してもかまわない。
解法
全探索する。ただし、愚直にやると間に合わないので、
状態を一つの整数として表わし、反転の操作をXOR一回でできるようにする。
ソースコード
char in[4][5]; int cng[16]; int main(){ rep(i,4)rep(j,4)rep(k,4) cng[i*4+j]|=1<<k*4+j|1<<i*4+k; int cur=0,ans=20,ansi; rep(i,4){ gets(in[i]); rep(j,4)if(in[i][j]=='+')cur^=1<<i*4+j; } rep(i,1<<16) { int tmp=cur,b=0; for(int j=i;j;j&=j-1)b++; rep(j,16)if(i&1<<j)tmp^=cng[j]; if(tmp)continue; if(b<ans)ans=b,ansi=i; } printf("%d\n",ans); rep(i,16)if(ansi&1<<i)printf("%d %d\n",i/4+1,i%4+1); return 0; }