1340: [蓝桥杯2017初赛]青蛙跳杯子 【中 / bfs / 有意思】

在这里插入图片描述
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;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值