题意:
4*4棋盘上有黑白棋子,通过最小次数的转换把棋盘上的棋子变为全白色或者全黑色。每次翻转棋子都要将其上下左右都翻转,每次翻转3-5个棋子。
思路:
题目类似于之前做的Poj_2965,更简单一点。思路就是状态压缩+bfs,自己推update函数推了半天。
代码实现:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 65536;
struct Node{
bool exist;
int times;
};
int pos;
int num;
int res;
Node lis[MAX];
unsigned short que[MAX];
void check(unsigned short cur);
unsigned short update(unsigned short cur,int type);
int main(){
unsigned short initial = 0;
char tmp;
int cnt = 0;
for( int i = 0; i < 4; i++ ){
for( int j = 0; j < 4; j++ ){
scanf("%c",&tmp);
if( tmp == 'b' ){
initial |= 1<<cnt;
}
cnt++;
}
getchar();
}
//check(initial);
if( initial==0xffff || initial==0 ){
printf("0\n");
return 0;
}
for( int i = 0; i < MAX; i++ ){
lis[i].exist = false;
lis[i].times = 0;
}
pos = 0;
num = 1;
res = 0;
que[pos] = initial;
while( pos < num ){
unsigned short cur = que[pos];
for( int i = 0; i < 16; i++ ){
unsigned short next = update(cur,i);
//check(initial);
//check(next);
if( lis[next].exist == true ){
continue;
}
if( next==0xffff || next==0 ){
res = lis[cur].times+1;
printf("%d\n",res);
return 0;
}
lis[next].exist = true;
lis[next].times = lis[cur].times+1;
que[num++] = next;
}
pos++;
}
printf("Impossible\n");
return 0;
}
unsigned short update(unsigned short cur,int type){
unsigned short tmp = 0;
switch(type){
case 0:
tmp = 0XC800;break;
case 1:
tmp = 0XE400;break;
case 2:
tmp = 0X7200;break;
case 3:
tmp = 0X3100;break;
case 4:
tmp = 0X8C80;break;
case 5:
tmp = 0X4E40;break;
case 6:
tmp = 0X2720;break;
case 7:
tmp = 0X1310;break;
case 8:
tmp = 0X08C8;break;
case 9:
tmp = 0X04E4;break;
case 10:
tmp = 0X0272;break;
case 11:
tmp = 0X0131;break;
case 12:
tmp = 0X008C;break;
case 13:
tmp = 0X004E;break;
case 14:
tmp = 0X0027;break;
case 15:
tmp = 0X0013;break;
}
return cur^tmp;
}
void check(unsigned short cur){
for( int i = 0; i < 4; i++ ){
for( int j = 0; j < 4; j++ ){
printf("%d ",cur%2);
cur /= 2;
}
printf("\n");
}
printf("\n");
}