POJ 1753 Flip Game(bfs枚举+递推)

来源:互联网 发布:淘宝上买火车票靠谱吗 编辑:程序博客网 时间:2024/06/08 18:24

题目地址:http://poj.org/problem?id=1753

这题此前曾经做过,但当时是用的纯BFS做的,然后后来又做了一次组队赛,那是16*16的,果断超时超内存。。能超的都超了。。于是又找了个更好的方法,就是枚举第一行,然后后面的根据第一行的情况推下去。比如,你要让所有的都变成W,如果上一行的对应位置是B的话,那它就必须要翻转。这样能保证前三行的都是W,然后只需判断最后一行就可以判断是不是全翻成了W。代码如下:

#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include<algorithm>using namespace std;int mp[20], min1, ff=0;struct node{    int a[20], x, ans;};void bfs(){    int i, j;    min1=1000000;    queue<node>q;    node f1, f2;    for(i=0; i<16; i++)    {        f1.a[i]=mp[i];    }    f1.x=0;    f1.ans=0;    q.push(f1);    while(!q.empty())    {        f1=q.front();        q.pop();        if(f1.x==4)        {            int ans1=0, ans2=0, flag=0;            for(i=0; i<16; i++)            {                f2.a[i]=f1.a[i];            }            f2.ans=f1.ans;            for(i=4; i<16; i++)            {                if(f2.a[i-4]==0)                {                    f2.a[i-4]=1-f2.a[i-4];                    f2.a[i]=1-f2.a[i];                    if(i%4>0)                        f2.a[i-1]=1-f2.a[i-1];                    if(i%4<3)                        f2.a[i+1]=1-f2.a[i+1];                    if(i+4<16)                        f2.a[i+4]=1-f2.a[i+4];                    ans1++;                }            }            for(i=12; i<16; i++)            {                if(f2.a[i]==0)                {                    flag=1;                    break;                }            }            if(flag==0)            {                if(min1>f2.ans+ans1)                    min1=f2.ans+ans1;                ff=1;            }            for(i=0; i<16; i++)            {                f2.a[i]=f1.a[i];            }            f2.ans=f1.ans;            flag = 0;            for(i=4; i<16; i++)            {                if(f2.a[i-4]==1)                {                    f2.a[i-4]=1-f2.a[i-4];                    f2.a[i]=1-f2.a[i];                    if(i%4>0)                        f2.a[i-1]=1-f2.a[i-1];                    if(i%4<3)                        f2.a[i+1]=1-f2.a[i+1];                    if(i+4<16)                        f2.a[i+4]=1-f2.a[i+4];                    ans2++;                }            }            for(i=12; i<16; i++)            {                if(f2.a[i]==1)                {                    flag=1;                    break;                }            }            if(flag==0)            {                if(min1>f2.ans+ans2)                    min1=f2.ans+ans2;                ff=1;            }            continue ;        }        for(i=0; i<16; i++)        {            f2.a[i]=f1.a[i];        }        f2.x=f1.x+1;        f2.ans=f1.ans;        q.push(f2);        f2.a[f1.x]=1-f1.a[f1.x];        if(f1.x>=1)        {            f2.a[f1.x-1]=1-f1.a[f1.x-1];        }        if(f1.x<3)        {            f2.a[f1.x+1]=1-f1.a[f1.x+1];        }        f2.a[f1.x+4]=1-f1.a[f1.x+4];        f2.ans=f1.ans+1;        q.push(f2);    }}int main(){    char s[10];    int i, j;    for(i=0; i<4; i++)    {        scanf("%s",s);        for(j=0; j<4; j++)        {            if(s[j]=='w')                mp[4*i+j]=1;            else                mp[4*i+j]=0;        }    }    bfs();    if(ff)        printf("%d\n",min1);    else        printf("Impossible\n");    return 0;}


0 0