http://oj.ecustacm.cn/problem.php?id=1340
转自: https://blog.dotcpp.com/a/69151
思路:
这是一道典型的bfs,青蛙每次可以跳到相邻杯子,隔着一个、两个跳到下个杯子,
那么就是每次可以越1,2,3,因为本题只有两个方向,所以在一维方向上表现为{1,2,3,-1,-2,-3};
跳跃我们可以认为是交换两个杯子里东西,因此用空的交换最好,即把空的当作一个青蛙;
所以接下来就是每次存放跳过后的序列,因为bfs是按层遍历,此时每种序列可能重复出现,
即跳过去又跳过来,我们就可以利用序列去重。
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
int st[6]={1,2,3,-1,-2,-3};
int sx,ans=0;
int sum=0;
map<string,int>mp; //利用map判断序列是否出现过,并去重
string s1,s2;
struct Node{ //定义结构体存放此时坐标,此时步数,此时序列
int x,k;
string sn;
};
void bfs(){ //bfs常规操作
queue<Node>q;
Node node;
node.x=sx;//空杯子起始点
node.k=0;
node.sn=s1;
mp[s1]=1;
q.push(node);
while(!q.empty()){
Node p=q.front();
for(int i=0;i<6;i++)
{
string s=p.sn;
int xx=p.x+st[i];
if(xx>=0&&xx<s1.length())
{
Node v;
swap(s[p.x],s[xx]);//起点 和 可到达的交换
if(mp[s]==1) continue;//重复了
mp[s]=1;
v.x=xx;
v.k=p.k+1;//步长
v.sn=s;//保存交换后的字符串
if(v.sn==s2){
ans=v.k;
return;
}
q.push(v);
}
}
q.pop();
}
}
int main()
{
cin>>s1>>s2;
for(int i=0;i<s1.length();i++)
{
if(s1[i]=='*') //找到那个空杯子
{
sx=i;
}
}
bfs();
cout<<ans<<endl;
return 0;
}
我的代码:
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
map<string,int>mp;
string s1,s2;
int ans;
int dx[10]={1,2,3,-1,-2,-3};
struct node
{
int x;
int step;
string s;
}Node;
void bfs(int x)
{
Node.x=x;
Node.step=0;
Node.s=s1;
mp[s1]=1;
queue<node> q;
q.push(Node);
while(!q.empty())
{
node top=q.front();
q.pop();
for(int i=0;i<6;i++)
{
int tempx=top.x+dx[i];
string ss=top.s;
if(tempx>=0&&tempx<s1.length())
{
swap(ss[top.x],ss[tempx]);
if(mp[ss]==1) continue; //重复了
mp[ss]=1;
node m;
m.x=tempx;
m.step=top.step+1;
m.s=ss;
if(m.s==s2)
{
ans=m.step;
return;
}
q.push(m);
}
}
}
}
int main(void)
{
cin>>s1>>s2;
for(int i=0;i<s1.length();i++)
{
if(s1[i]=='*')
{
bfs(i);
break;
}
}
cout<<ans<<endl;
return 0;
}
简写版:
#include<cstdio>
#include<iostream>
#include<string>
#include<queue>
#include<map>
using namespace std;
string s1,s2;
int startx;
int dx[6]={1,2,3,-1,-2,-3};
struct node
{
int x,step;
string s;
}Node;
void bfs(int x)
{
Node.x=x,Node.step=0,Node.s=s1;
queue<node>q; q.push(Node);
map<string,int>mp; mp[s1]=1;
while(!q.empty())
{
node top=q.front(); q.pop();
for(int i=0;i<6;i++)
{
int tempx=top.x+dx[i];
if(tempx<0||tempx>=s1.length()) continue;
string str=top.s;
swap(str[top.x],str[tempx]);
if(!mp[str])
{
node m;
m.x=tempx,m.step=top.step+1,m.s=str;
mp[str]=1;
if(str==s2)
{
cout<<m.step<<endl;
return;
}
q.push(m);
}
}
}
}
int main(void)
{
while(cin>>s1>>s2)
{
for(int i=0;i<s1.size();i++) if(s1[i]=='*') startx=i;
bfs(startx);
}
return 0;
}