【POJ 1753】Flip Game

来源:互联网 发布:开淘宝网店的条件 编辑:程序博客网 时间:2024/05/29 13:16

【POJ 1753】Flip Game

二进制+(BFS)暴力枚举

原本用二位字符数组存 发现遍历困难 并且翻动棋子也难办 后来想到一维线性
下标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
在图中即为
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
预处理出一个数组进行翻转 后来又发现预处理难办 灵光一现 由于只有黑白两色 可用1 0标记 看到1 0想到的当然就是二进制了 并且又做成了个线性 刚好16位二进制 一切迎刃而解 翻转可用二进制运算^(异或) 上代码

#include <cstdio>#include <cstdlib>#include <cstring>#include <queue>#define INF 0x3f3f3f3fusing namespace std;int ms;int step[65536];int dir[32];bool vis[65536];int tp;int GetNum(char *str)//黑1 白 0{    int i,x = 0;    for(i = 1; i <= 16; ++i)    {        x <<= 1;        x += (str[i] == 'b')? 1: 0;    }    return x;}//void PrintNum(int x)//{//    int i = 1;//    while(x)//    {//        if(x&1) printf("1 ");//        else printf("0 ");//        x >>= 1;//        if(!(i%4)) printf("\n");//        ++i;//    }//    for(; i <= 16; ++i)//    {//        printf("0 ");//        if(!(i%4)) printf("\n");//    }//    printf("\n\n");//}void Memset(char *str,char a){    int i,j;    for(i = 1; i <= 16; ++i)            str[i] = a;}void Getdir(){    tp = 0;    char str[49];    int i,j;    Memset(str,'w');    for(i = 16; i >= 1; --i)    {        str[i+1] = str[i+5] = str[i+2]= 'w';        if(i-3 > 0) str[i-3] = 'w';        str[i] = str[i+4] = 'b';        if(i%4) str[i+1] = 'b';        if((i-1)%4) str[i-1] = 'b';        if(i-4 > 0) str[i-4] = 'b';        dir[tp++] = GetNum(str);    }}void Bfs(){    memset(step,INF,sizeof(step));    memset(vis,0,sizeof(vis));    step[ms] = 0;    int i,x,v;    queue <int> q;    q.push(ms);    while(!q.empty())    {        x = q.front();        q.pop();        vis[x] = 0;        for(i = 0; i < tp; ++i)        {            v = x^dir[i];            if(step[v] > step[x]+1)            {                step[v] = step[x]+1;                if(!vis[v])                {                    q.push(v);                    vis[v] = 1;                }            }        }    }}int main(){    //freopen("in.txt","r",stdin);    char str[18];    int i,j,x;    for(i = 1; i < 17; i += 4)    {        scanf("%s",str+i);    }    ms = GetNum(str);    Getdir();//    for(i = 0; i < tp; ++i)//        PrintNum(dir[i]);    if(ms == 0 || ms == 65535) printf("0\n");    else    {        Bfs();        x = min(step[0],step[65535]);        if(x == INF) printf("Impossible\n");        else printf("%d\n",x);    }    return 0;}
0 0
原创粉丝点击