POJ

来源:互联网 发布:中国食品安全数据库 编辑:程序博客网 时间:2024/06/04 01:06

题目链接: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 0x3f3f3f3fusing namespace std;typedef long long LL;typedef pair<int, int> P;const int maxn = 5e5 + 5;int mp[4][4];//w->0,b->1int 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;}