HDU 3355 Hop — Don’t Walk!

39 篇文章 0 订阅
Problem Description
KERMIT THE FROG is a classic video game with a simple control and objective but requires a good deal of thinking.
You control an animated frog that can walk and hop, in both forward and backward directions. The frog stands in a space between an otherwise a contiguous line of tiles. Each tile is painted black on one side, and white on the other. The frog can walk (forward, or backward) over an adjacent tile (in front or behind him.)
When the frog walks over a tile, the tile slides to the space where the frog was standing. For example, in the adjacent figure, the frog has two tiles behind him, and three in front. We’ll use the notation BWFBBW to refer to this situation where F refers to the space (where the frog is standing,) B is a tile with its black face showing, while W is a tile with its white face showing. The forward direction is from left to right. If the frog were to walk forward, the resulting situation is BWBFBW. Similar behavior when the frog walks backward, the tile behind the frog slides to where the frog was standing. The frog can also hop over the tiles. The frog can hop over an adjacent tile landing on the tile next to it. For example, if the frog was to hop backward, it would land on the first (left-most) tile, and the tile would jump to the space where the frog was standing. In addition, the tile would flip sides. For example, hopping backward in the figure would result in the situation: FWWBBW. We challenge you to write a program to determine the minimum number of moves (walks or hops) to transform one tile configuration into another.

 

Input
Your program will be tested on one or more test cases. Each test case is specified on a single line that specifies string S representing the initial tile arrangement. S is a non-empty string and no longer than 100 characters and is made of the letters ’B’, ’W’, and exactly one ’F’. The last line of the input file has one or more ’-’ (minus) characters.
 

Output
For each test case, print the following line:
k. M
Where k is the test case number (starting at one,) and M is the minimum number of moves needed to transform the given arrangement to an arrangement that has no white tile(s) between any of its black tiles . The frog can be anywhere. M is -1 if the problem cannot be solved in less than 10 moves.
Note: There is a blank space before M.
 

Sample Input
  
  
WWBBFBW WWFBWBW FWBBWBW ---
 

Sample Output
  
  
1. 0 2. 1 3. 2

bfs,注意判断结束状态。

#include<map>
#include<queue>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define make(x,y) make_pair(x,y)
#define pii pair<bitset<N>,pair<int,int> >
#define fi first
#define se second
#define rep(i,j,k) for (int i=j;i<=k;i++)
const int N=105;
int T=0,y,len;
char s[N];
bitset<N> x;

struct point
{
    bitset<N> a;
    int wz;
    point(bitset<N> a,int wz):a(a),wz(wz){}
    bool operator<(const point b)const
    {
        rep(i,0,N-1)
        {
            if (a[i]==b.a[i]) continue;
            else return a[i]<b.a[i];
        }
        return wz<b.wz;
    }
};

map<point,bool> M;

bool check(bitset<N> x,int y)
{
    int tot=x.count();
    for(int i=0;i<len;i++)
    {
        if (!x[i]) continue;
        if (i<y)
        {
            rep(j,i,i+tot-2) if (!x[j]) return false;
            return x[i+tot-1]||y>=i+tot;
        }
        if (i==y) tot--;
        if (i>y)
        {
            rep(j,i,i+tot-1) if (!x[j]) return false;
            return true;
        }
    }
    return true;
}


int bfs()
{
    queue<pii> p;    
    p.push(make(x,make(0,y)));
    if (check(x,y)) return 0;
    while (!p.empty())
    {
        pii q=p.front(); p.pop();
        if (q.se.first==9) return -1;
        int step=q.se.fi,now=q.se.se;
        if (now>0)
        {    
            bitset<N> t=q.fi;
            t[now]=t[now-1];
            t[now-1]=1;
            if (!M[point(t,now-1)]) 
            {
                if (check(t,now-1)) return step+1;
                M[point(t,now-1)]=true;
                p.push(make(t,make(step+1,now-1)));
            }
        }
        if (now+1<len)
        {
            bitset<N> t=q.fi;
            t[now]=t[now+1];
            t[now+1]=1;
            if (!M[point(t,now+1)]) 
            {
                if (check(t,now+1)) return step+1;
                M[point(t,now+1)]=true;
                p.push(make(t,make(step+1,now+1)));
            }
        }
        if (now>1)
        {    
            bitset<N> t=q.fi;
            t[now]=t[now-2];
            t[now-2]=1;
            t.flip(now);
            if (!M[point(t,now-2)]) 
            {
                if (check(t,now-2)) return step+1;
                M[point(t,now-2)]=true;
                p.push(make(t,make(step+1,now-2)));
            }
        }
        if (now+2<len)
        {
            bitset<N> t=q.fi;
            t[now]=t[now+2];
            t[now+2]=1;
            t.flip(now);
            if (!M[point(t,now+2)]) 
            {
                if (check(t,now+2)) return step+1;
                M[point(t,now+2)]=true;
                p.push(make(t,make(step+1,now+2)));
            }
        }
    }
    return -1;
}

int main()
{
    while (~scanf("%s",s),s[0]!='-')
    {
        x.reset();
        M.clear();
        len=strlen(s);
        for (int i=0;s[i];i++) 
        {
            x[i]=s[i]!='W';
            if (s[i]=='F') y=i;
        }
        printf("%d. %d\n",++T,bfs());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值