HDU - 1430(BFS)

原文链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430

思路:

题目说求出最少的变换步骤,那么首选BFS搜索,看了网上一些人写的用的多是康托展开,但感觉这里不必用康托展开就行,但BFS预处理还是必须的。这是因为BFS作为广度搜索如果我们对于每个测试用例都去用一遍BFS的话,很有可能出现TLE,所以在BFS中常用的是BFS预处理,即一开始就把所有情况搜索出来,然后对于多种测试用例,调取预处理后的结果输出即可。

这道题在这里有个思路,就是再进行BFS预处理之后,我们需要把所有的初始状态到最终状态映射成“12345678”到相对应的结果状态,通过这个思路找到对应的步骤方式。是一道有难度的BFS搜索问题

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
string st,ed;
map<string,string>mapp;
map<string,string>::iterator it;
struct magic
{
    string str;//记录各种状态
    string alp;//记录操作字符
};
string a(string x)//a变换
{
    string ans="";
    for(int i=x.size()-1;i>=0;i--)
    {
        ans+=x[i];
    }
    return ans;
}
string b(string x)//b变换
{
    string ans="";
    ans+=x[3];ans+=x[0];ans+=x[1];ans+=x[2];ans+=x[5];ans+=x[6];ans+=x[7];ans+=x[4];
    //执行b变换的操作
    return ans;
}
string c(string x)//c变换
{
    string ans="";
    ans+=x[0];ans+=x[6];ans+=x[1];ans+=x[3];ans+=x[4];ans+=x[2];ans+=x[5];ans+=x[7];
    return ans;
}
void BFS()//预处理所有的变换情况
{
    magic now,next;
    now.str="12345678";
    now.alp="";
    queue<magic>q;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        it=mapp.find(now.str);
        if(it!=mapp.end())//为了让字典序最小,删掉已经找到的路
            continue;
        mapp[now.str]=now.alp;//存储不同状态
        next.str=a(now.str);next.alp=now.alp+'A';
        q.push(next);
        next.str=b(now.str);next.alp=now.alp+'B';
        q.push(next);
        next.str=c(now.str);next.alp=now.alp+'C';
        q.push(next);
    }
}
//这里有个思路,就是再进行BFS预处理之后,我们需要把所有的初始状态到最终状态映射成“12345678”到相对应的结果状态,通过这个思路找到对应的步骤方式
int main()
{
    BFS();
    while(cin>>st>>ed)
    {
        string ans="";
        for(int i=0;i<8;i++)
        {
            for(int j=0;j<8;j++)//找到变换前后对应的位置
            {
                if(ed[i]==st[j])//通过累加每一位不同的值,得到一个数用于代表不同的状态
                    ans+=j+'0'+1;//这里注意是通过结果找到从原来的位置移动到结果位置所移动的位置数
            }
        }
        cout<<mapp[ans]<<endl;//找到相对应的移动的方式
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值