POJ1753 Flip Game

来源:互联网 发布:程序员自我修养阶段 编辑:程序博客网 时间:2024/05/17 19:57

http://poj.org/problem?id=1753


题意:一个类似点灯游戏的东西,求灯全亮或全灭的最小步数。


一般想到是BFS,但是武大给的是枚举,果然是枚举啊啊啊啊!!因为点某几个灯之后的结果是相同的,与点这几个灯的顺序无关!


#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<vector>#include<algorithm>#include<map>#include<cmath>using namespace std;#define N 100005bool c[5][5],a[5][5];int x,y,b[20]={0};void init(){    int i,j;    for (i=1;i<=4;i++)    for (j=1;j<=4;j++)    a[i][j]=c[i][j];}void bplus()//把b作为一个从0到2^16-1的数字的二进制表达的串{    b[16]++;    int i=16;    while (b[i]==2)    {        b[i]=0;        b[i-1]++;        i--;    }}void getxy(int m){    x=(m-1)/4+1;    y=m%4;    if (y==0) y=4;}void fan(int x,int y){    a[x][y]=!a[x][y];}bool check(){    int sum=0,i,j;    for (i=1;i<=4;i++)    for (j=1;j<=4;j++)    if (a[i][j]==true) sum++;    if (sum==0 || sum==16) return true;    else return false;}int count(){    int i,sum=0;    for (i=1;i<=16;i++) sum+=b[i];    return sum;}int main(){    //freopen("a","r",stdin);    int j,i,min=100;    char ch;    for (i=1;i<=4;i++)    {        for (j=1;j<=4;j++)        {            cin>>ch;            if (ch=='b') c[i][j]=false;            else c[i][j]=true;        }    }    b[16]=-1;    for (i=0;i<=65535;i++)//枚举该翻哪些点    {        init();        bplus();        for (j=1;j<=16;j++)        if (b[j]==1)        {            getxy(j);            fan(x,y);            if (x>1) fan(x-1,y);            if (x<4) fan(x+1,y);            if (y>1) fan(x,y-1);            if (y<4) fan(x,y+1);        }        if (check())        {            if (count()<min) min=count();        }    }    if (min<100) cout<<min;    else cout<<"Impossible";    return 0;}