POJ1753 Flip Game
Idea
仅仅需要枚举第一行就行了, 其他行可以用上面的情况分别写出.
注意可以使用宏定义简化代码的编写, 减小调试难度.
注意if(){}
的大括号总是要加.
Code
#include <iostream>
#include <string>
using namespace std;
#define F(i, a, b) for(int i=(a); i<=(b);i++)
#define Fd(i, a, b) for(int i=(a);i>=(b);i--)
char s[4][4];
char ori[4][4];
bool chk(){
int a = -1;
F(i, 0, 3)F(j, 0, 3) {
if(a == -1){
a=(s[i][j]=='w'?1:0);
}else{
if(a!=(s[i][j]=='w'?1:0)){
// printf("Fail");
return false;
}
}
}
// printf("Success");
return true;
}
#define isin(x, y) (x>=0 && x<4 && y>=0 && y<4)
#define change(x, y) if(s[x][y]=='b') {s[x][y]='w';} else{ s[x][y]='b'; }
#define judge(x, y) if(isin(x, y)){ change(x, y);}
void press(int x, int y){
judge(x, y);
judge(x-1, y);
judge(x+1, y);
judge(x, y-1);
judge(x, y+1);
}
void restore(){
F(i, 0, 3) F(j, 0, 3) s[i][j] = ori[i][j];
}
int mintms= 114514191;
int ntimes = 0;
signed main(){
F(i, 0, 3) scanf("%s", ori[i]);
restore();
#define white(x, y) (s[x][y]=='w')
#define black(x, y) (s[x][y]=='b')
#define updt(x) mintms=min(mintms, x)
F(l, 0, ((1<<4)-1)){
// printf("l=%d\n", l);
int tmp = l, i=0;
while(i<4){
if(tmp&1) {ntimes ++;press(0, i);}
tmp>>=1, i++;
}
F(i, 1, 3){
F(j, 0, 3){
if(black(i-1, j)) {press(i, j); ntimes++;}
}
}
if(chk()) updt(ntimes);
ntimes=0;
// F(i, 0, 3) {F(j, 0, 3) printf("%c", s[i][j]); printf("\n");}
restore();
}
F(l, 0, ((1<<4)-1)){
// printf("l=%d\n", l);
int tmp = l, i=0;
while(i<4){
if((tmp&1)) {ntimes++;press(0, i);}
// cout<<"+";
tmp>>=1, i++;
}
F(i, 1, 3){
F(j, 0, 3){
if(white(i-1, j)) {press(i, j); ntimes++;}
}
}
if(chk()) updt(ntimes);
ntimes=0;
// F(i, 0, 3) {F(j, 0, 3) printf("%c", s[i][j]); printf("\n");}
restore();
}
if(mintms == 114514191) cout<<"Impossible"<<endl;
else cout<<mintms<<endl;
}