[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;
}

浙公网安备 33010602011771号