八数码

八数码_第1张图片
求最短路径,bfs可以解决
看题目的意思就是给出一个3*3的矩阵,要求通过x的位置变化,然后让矩阵变的有序,即下面的矩阵

1 2 3
4 5 6
7 8 x

如果能够得到上面的矩阵,则输出x移动最少的次数,如果不能得到那么就输出-1
对于这个问题的话我们可以把矩阵变成一个长度为9的字符串,然后bfs,每次都得找到x的位置,然后再转化成坐标(x,y)来进行判断上、下、左、右四个方向,哪个方向可以走(肯定是不能超出3*3矩阵的范围),然后再判断一下新的状态是否到达过,如果没有,那么到达这个新的状态x移动次数最少,因此,如果再有其他状态可以通过x的移动到达这个状态,那么就不需要处理!!!因为第一次到达了这个状态了的时候,肯定就是x移动最少的时候。
题目链接
这个题目还有一个坑的地方就是必须使用unordered_map,一开始我使用map的话TLE了…这是因为unordered_map内部用的是哈希表,查找表较快,map内部用的是红黑树,因为我们找的时候是无序的,因此红黑树对我们的作用并不是很大!!!

#include
#include
#include
#include
#include
using namespace std;
int bfs(string start)
{
    string end="12345678x";
    int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
    queue<string>q;
    unordered_map<string,int>d;
    q.push(start);
    d[start]=0;
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        int distance=d[t];
        int idx=t.find('x');
        if(end==t) return distance;
        for(int i=0;i<4;i++)
        {
            int xx=dx[i]+idx/3,yy=dy[i]+idx%3;
            if(xx>=0&&xx<3&&yy>=0&&yy<3)
            {
                swap(t[idx],t[3*xx+yy]);
                if(!d.count(t)) d[t]=distance+1,q.push(t);
                swap(t[idx],t[3*xx+yy]);
                //这里记得还原状态
            }
        }
    }
    return -1;
}
int main()
{
    string start;
    char tmp;
    for(int i=0;i<9;i++) cin>>tmp,start+=tmp;
    cout<<bfs(start)<<endl;
    return 0;
}

你可能感兴趣的:(基础算法)