poj1753 Flip Game

#include<iostream>
using namespace std;
//#define REVERSE(DATA,BIT) DATA^(1<<BIT)
bool v[65535];
int head,tail;
struct point{
    int dis;
    unsigned short state;
};
point Q[65535];
int bfs();
bool vis(point& t);
unsigned short move(unsigned short state, int i);
int main()
{   
    int l=bfs();
    if(l<0)
        cout<<"Impossible"<<endl;
    else
        cout<<l<<endl;
    return 0;
}
bool vis(point& t)
{   
    if(v[t.state])
        return true;
    v[t.state]=1;
    return false;
}
int bfs()
{   
    point t,now,ext;
    int i=0,j=0,c;
    char str[5][5]; //注意,定义长度时要大于4*4,一定要包含结束符,不然提交之后是WA
    t.state=0;
    memset(v,0,sizeof(v));
    for(i=1;i<=4;i++)
    {
        cin>>str[i-1];
    }
    for(i=0;i<4;i++)
        for(j=0;j<4;j++)
        {
            if(str[i][j]=='b')
                c=1;
            else
                c=0;
            t.state|=c<<(i*4+j);
        }
        t.dis=0;
        head=tail=0;
        Q[tail++]=t;
    //    vis(t);
        v[t.state]=1;
        while(head<tail)
        {   
            now=Q[head++];
            if(now.state==0 || now.state==65535)       
                return now.dis;
            int s=now.state; 
            unsigned short temp=0;   
            for(i=0;i<16;++i)
            {
                temp=0;
                temp |= (1<<i);
                if((i+1)%4!=0)
                    temp |= (1<<(i+1)); 
                if(i%4 != 0)
                    temp |= (1<<(i-1));
                if(i+4 < 16)
                    temp |= (1<<(i+4));
                if(i-4 >= 0)
                    temp |= (1<<(i-4));
                ext.state=s^temp;
                ext.dis=now.dis+1;
                if(!vis(ext))
                {
                    Q[tail++]=ext;
                }
            }
        }
    return -1;
}

注:本题的技巧在于如何表示所有可能出现得plates状态,一共16个盘子,可以使用16位来表示,即两个字节。本题涉及到对某一位求反,可用函数REVERSE(DATA,BIT) DATA^(1<<BIT)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
POJ1753题目为"Flip Game",题目给出了一个4x4的棋盘,每个格子有黑色或白色,每次翻转一个格子会同时翻转它上下左右四个格子的颜色,目标是把整个棋盘都变为同一种颜色,求把棋盘变成同种颜色的最小步数。 解题思路: 一般关于棋盘变色的题目,可以考虑使用搜索来解决。对于POJ1753题目,可以使用广度优先搜索(BFS)来解决。 首先,对于每个格子,定义一个状态,0表示当前格子是白色,1表示当前格子是黑色。 然后,我们可以把棋盘抽象成一个长度为16的二进制数,将所有格子的状态按照从左往右,从上往下的顺序排列,就可以用一个16位的二进制数表示整个棋盘的状态。例如,一个棋盘状态为: 0101 1010 0101 1010 则按照从左往右,从上往下的顺序把所有格子的状态连接起来,即可得到该棋盘的状态为"0101101001011010"。 接着,我们可以使用队列来实现广度优先搜索。首先将初始状态加入队列中,然后对于队列中的每一个状态,我们都尝试将棋盘上的每个格子翻转一次,生成一个新状态,将新状态加入队列中。对于每一个新状态,我们也需要记录它是从哪个状态翻转得到的,以便在得到最终状态时能够输出路径。 在搜索过程中,我们需要维护每个状态离初始状态的步数,即将该状态转换为最终状态需要的最小步数。如果我们找到了最终状态,就可以输出答案,即最小步数。 代码实现:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值