给定一个布满黑白棋的棋盘,你有四种翻法可以选,一旦选了一种翻法,在当局游戏中就只能使用这种翻法。某种翻法是指,当你翻某个棋子时,其上下左右多少个也会一起跟着翻面。问能否翻成全白,翻成全白所需要的最少步数以及所选的翻法。若多种翻法都可达到最小步数,优先使用编号小的翻法。
数据范围:15*15的棋盘,四种翻法在题面里给出,与输入无关。
对于第一种翻法,如果确定了第一排15个的情况,即翻或不翻,为了把第一排清成全白,就能知道第二排的15个的情况,以此类推就可以推到最后一排。所以枚举第一排的15个翻的情况即可。
对于剩下三种同理,枚举最后一列/第一列翻的情况即可。
代码写的可搓了...
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m,nn,mm,ans,anskind;
bool a[15][15],d[15][15];
int b[15],c[16];
inline void update(int &a,int b) {
if (b!=-1&&(a==-1||a>b)) a=b;
}
inline int nbits(int x) {
int ans=0;
while (x) {
ans+=x&1;
x>>=1;
}
return ans;
}
void bitprint(int x) {
while (x) {
printf("%d",x&1);
x>>=1;
}
printf("\n");
}
int try1(int o) {
int ans=nbits(o);
c[0]^=o;
c[0]^=o<<1&mm;
c[0]^=o>>1;
c[1]^=o;
for (int i=1;i<n;i++) {
int tmp=c[i-1];
ans+=nbits(tmp);
c[i]^=tmp;
c[i]^=tmp<<1&mm;
c[i]^=tmp>>1;
c[i+1]^=tmp;
}
if (c[n-1]) return -1;
return ans;
}
int try2(int o) {
int ans=nbits(o);
c[0]^=o;
c[0]^=o<<1&mm;
c[1]^=o<<1&mm;
c[1]^=o>>1;
c[1]^=o;
for (int i=1;i<n;i++) {
int tmp=c[i-1];
ans+=nbits(tmp);
c[i]^=tmp;
c[i]^=tmp<<1&mm;
c[i+1]^=tmp<<1&mm;
c[i+1]^=tmp>>1;
c[i+1]^=tmp;
}
if (c[n-1]) return -1;
return ans;
}
int try3(int o) {
int ans=nbits(o);
c[0]^=o;
c[0]^=o<<1&mm;
c[0]^=o>>1;
c[1]^=o<<1&mm;
c[1]^=o;
for (int i=1;i<n;i++) {
int tmp=c[i-1];
ans+=nbits(tmp);
c[i]^=tmp;
c[i]^=tmp<<1&mm;
c[i]^=tmp>>1;
c[i+1]^=tmp<<1&mm;
c[i+1]^=tmp;
}
if (c[n-1]) return -1;
return ans;
}
int try4(int o) {
int ans=nbits(o);
c[0]^=o;
c[0]^=o<<1&mm;
c[0]^=o>>1;
c[1]^=o<<1&mm;
c[1]^=o>>1;
for (int i=1;i<n;i++) {
int tmp=c[i-1];
ans+=nbits(tmp);
c[i]^=tmp;
c[i]^=tmp<<1&mm;
c[i]^=tmp>>1;
c[i+1]^=tmp<<1&mm;
c[i+1]^=tmp>>1;
}
if (c[n-1]) return -1;
return ans;
}
void getb() {
int i,j;
for (i=0;i<n;i++) {
int tmp=0;
for (j=0;j<m;j++) {
tmp<<=1;
tmp|=a[i][j];
}
b[i]=tmp;
}
}
void flip1() {
int i,j,o,oldans=ans;
getb();
for (o=0;o<=mm;o++) {
memcpy(c,b,sizeof(b));
update(ans,try1(o));
}
if (oldans!=ans) anskind=1;
}
void flip2() {
int i,j,o,oldans=ans;
getb();
for (o=0;o<=mm;o++) {
memcpy(c,b,sizeof(b));
update(ans,try2(o));
}
if (oldans!=ans) anskind=2;
}
void flip3() {
int i,j,o,oldans=ans;
getb();
for (o=0;o<=mm;o++) {
memcpy(c,b,sizeof(b));
update(ans,try3(o));
}
if (oldans!=ans) anskind=3;
}
void flip4() {
int i,j,o,oldans=ans;
getb();
for (o=0;o<=mm;o++) {
memcpy(c,b,sizeof(b));
update(ans,try4(o));
}
if (oldans!=ans) anskind=4;
}
int main() {
int i,j;
while (scanf("%d%d",&n,&m),n!=0) {
nn=(1<<n)-1;mm=(1<<m)-1;
for (i=0;i<n;i++)
for (j=0;j<m;j++) {
char c;
scanf(" %c",&c);
a[i][j]=(c=='1');
}
ans=-1;anskind=-1;
flip1();
for (i=0;i<n;i++)
for (j=0;j<m;j++)
d[m-j-1][i]=a[i][j];
swap(n,m);
nn=(1<<n)-1;mm=(1<<m)-1;
for (i=0;i<n;i++)
for (j=0;j<m;j++)
a[i][j]=d[i][j];
flip2();
for (i=0;i+i<n;i++)
for (j=0;j<m;j++)
swap(a[i][j],a[n-i-1][j]);
flip3();
flip4();
if (ans!=-1) printf("%d %d\n",anskind,ans);
else printf("Impossible\n");
}
return 0;
}