题目链接:http://poj.org/problem?id=1753
题意:4*4的有黑白棋子的格子,问你最少要多少步把棋子全变成黑色或白色,(每反转一个棋子就会把它上下左右的棋子变色)
思路:就是一个反转题,我直接给分成白色和黑色两种情况,所以代码有点冗长,但还是比较好理解的,具体看代码注释
具体还有啥不明白可以看我另一篇同类型的题的博客:http://blog.csdn.net/lll_yx/article/details/76943982
代码:
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <numeric>
#include <set>
#include <string>
#include <cctype>
#include <sstream>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 5e5 + 5;
int mp[4][4];//w->0,b->1
int to[4][2]={0,1,0,-1,1,0,-1,0};
int Ans0[4][4],ans0; //所有后面带0的都是白色的情况,1是黑色
int Ans1[4][4],ans1;
int ok0(int x,int y){//返回(x,y)点的颜色
int c=Ans0[x][y];
for (int i=0;i<4;i++){
int dx=x+to[i][0];
int dy=y+to[i][1];
if (dx<0||dx>=4||dy<0||dy>=4) continue;
c+=Ans0[dx][dy];
}
c+=mp[x][y];
return c%2;
}
int ok1(int x,int y){
int c=Ans1[x][y];
for (int i=0;i<4;i++){
int dx=x+to[i][0];
int dy=y+to[i][1];
if (dx<0||dx>=4||dy<0||dy>=4) continue;
c+=Ans1[dx][dy];
}
c+=mp[x][y];
return c%2;
}
int calc0(){//计算反转的次数
for (int i=1;i<4;i++){
for (int j=0;j<4;j++){
if(ok0(i-1,j)) Ans0[i][j]=1;
}
}
for (int i=0;i<4;i++){
if(ok0(3,i)) return -1;
}
int cnt=0;
for (int i=0;i<4;i++){
for (int j=0;j<4;j++){
cnt+=Ans0[i][j];
}
}
return cnt;
}
int calc1(){
for (int i=1;i<4;i++){
for (int j=0;j<4;j++){
if(!ok1(i-1,j)) Ans1[i][j]=1;
}
}
for (int i=0;i<4;i++){
if(!ok1(3,i)) return -1;
}
int cnt=0;
for (int i=0;i<4;i++){
for (int j=0;j<4;j++){
cnt+=Ans1[i][j];
}
}
return cnt;
}
int main () {
//freopen ("in.txt", "r", stdin);
for (int i=0;i<4;i++){
for (int j=0;j<4;j++){
char c;
cin>>c;
if (c=='w') mp[i][j]=0;
else mp[i][j]=1;
}
}
int ans0=INF,ans1=INF;
for (int i=0;i<16;i++){
memset(Ans0,0,sizeof(Ans0));
memset(Ans1,0,sizeof(Ans1));
for (int j=0;j<4;j++){
if (i&(1<<j)) Ans0[0][j]=Ans1[0][j]=1;
}
int num0=calc0();
if (num0<ans0&&num0!=-1){
ans0=num0;
}
int num1=calc1();
if (num1<ans1&&num1!=-1){
ans1=num1;
}
}
int ans=min(ans0,ans1);
if (ans==INF) printf ("Impossible\n");
else printf ("%d\n",ans);
return 0;
}