[HDU] 3355 Hop — Don’t Walk! [BFS]

题目来源:HDOJ 3355 [2009 ANARC]

题目大意:给定一条由一个个小方块组成的直线小路,有一只青蛙停在其中的一块小方块上,小方块分黑白两种,分别用字母B和W表示。青蛙停的位置则由字母F表示。按一定规则操作后,使得在黑方块中没有白方块存在。规则如下:青蛙共有4种选择,假设还有路的话,可以选择前进一步(即F?变成?F,其中?代表W或B,下同),或后退一步(?F变成F?),或前进两步(F?B变成W?F),或后退两步(W?F变成F?B)。问:最少需要几步才能达到预定结果?

简单分析:首先,要说明的是题目中有提到,当步数大于10的时候,就不用再继续走了,直接输出-1就可以了。这个很关键,因为,这样一来,最多只用走9步,即便给出所有的不同的方案总共也只有4^9=262144种。所以,用BFS来遍历各种方案后的状态就可以了。不过,一开始,我超时了很多次,因为,当时在BFS中另外开设了一个set<sting> visited用来存放已有的状态,然后用visited.count(v)==0来判断是否已存在,但是这样在遍历的时候似乎加重了程序开销(具体原因,待以后分析),之后,用原本存放步数的map<string int>同时用来判断,即step.find(v)==step.end(),并且最后把原本在if语句的最终状态判断语句if(is(v)) return step[v]放到了if里面(我想这一步,也能缩短时间,因为提前可以做判断了,不过对于超过9步的数据来说是无视了),这样就能AC了,不过时间也不少,640MS。

AC代码如下:

#include<iostream>
#include<map>
#include<string>
#include<queue>
using namespace std;

bool is(string s)
{
	int i,k=0,flag=0,t=0;
    int n=s.size();
    for(i=0;i<n;++i) {
        if(s[i]=='W'&&flag==1) k++;
        if(s[i]=='B') {
            flag=1;
            if(k!=0) {
                t=1;
                break;
            }
        }
    }
    if(t) return false;
    else return true;
}

int BFS(string s)
{
	queue<string> Qu;
	int len=s.size(),f;
	string u,v;
	map<string,int> step;
	step[s]=0;
	Qu.push(s);
	while(!Qu.empty()) {
		u=Qu.front();
		Qu.pop();
		if(step[u]>=10) return -1;
		f=u.find('F');
		v=u;
		if(f+1<len) {
			v[f]=v[f+1];
			v[f+1]='F';
			if(step.find(v)==step.end()) {
				step[v]=step[u]+1;
				if(is(v)) return step[v];
				Qu.push(v);
			}
		}
		v=u;
		if(f-1>=0) {
			v[f]=v[f-1];
			v[f-1]='F';
			
			if(step.find(v)==step.end()) {
				step[v]=step[u]+1;
				if(is(v)) return step[v];
				Qu.push(v);
			}
		}
		v=u;
		if(f+2<len) {
			if(v[f+2]=='B')
				v[f]='W';
			if(v[f+2]=='W')
				v[f]='B';
			v[f+2]='F';
			
			if(step.find(v)==step.end()) {
				step[v]=step[u]+1;
				if(is(v)) return step[v];
				Qu.push(v);
			}
		}
		v=u;
		if(f-2>=0) {
			if(v[f-2]=='B')
				v[f]='W';
			if(v[f-2]=='W')
				v[f]='B';
			v[f-2]='F';
			if(step.find(v)==step.end()) {
				step[v]=step[u]+1;
				if(is(v)) return step[v];
				Qu.push(v);
			}
		}
	}
	return -1;
}

int main()
{
	string state;
	int count=1,r;
	while(cin>>state)
	{
		if(state[0]=='-') break;
		if(is(state)) cout<<count++<<". 0"<<endl;
		else {
			r=BFS(state);
			r==-1?cout<<count++<<". -1"<<endl:cout<<count++<<". "<<r<<endl;
		}
	}
	return 0;
}
posted @ 2010-04-02 21:36  timebug  Views(529)  Comments(0Edit  收藏  举报