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;
	
}
posted @ 2022-11-26 15:40  Micoael_Primo  阅读(27)  评论(0)    收藏  举报