题解 P1379 【八数码难题】

事实证明一个map+单向bfs会被新的,强大的数据卡掉一个点233


显然一共有9!种情况,而且这个数不是很大

所以我们可以直接打一个单向bfs

将每一种状态都看成是一个字符串,那么我们在找到'0'的位置后按常理来说可以往"上,下,左,右"四个方向进行交换,那么很容易看出如果将这个3*3的矩形转换为了一个字符串后,这四个方向分别对应的变换位置就是{-3,3,-1,1},那么这样的话就可以很容易的用字符串表示当前的状态并进行转化

打广搜的话,很明显要记忆化,不然那么多种状态,那么多重复,不爆队列就怪了

更改了判重的方法,改为了更快的hash,就不会爆了


#include <stdio.h>
#include <string>
#include <cstring>
#include <map>
#include <iostream>
#include <queue>
#include <cstdlib>
using namespace std;
#define p 10000007
string start, ed="123804765";
int h[p+1];
int dx[5]={0,1,-1,3,-3};
int fl=0;
int insert(int x)
{
    int i=x%p;
    while (h[i]!=0) i=(i+1)%p;
    h[i]=x;
}
int find(int x)
{
    int i=x%p;
    while (h[i]!=0&&h[i]!=x) i=(i+1)%p;
    if (h[i]==x) return 1;
    return 0;
}
int bfs()
{
    queue<string> t;
    queue<int> state;
    t.push(start);
    state.push(0);
    int xx=std::atoi(start.c_str());
    insert(xx);
    while (!t.empty())
    {
        string now = t.front();
        int ns = state.front();
        t.pop(); state.pop();
        int l = now.find('0');
        for (int i = 1; i <= 4; i++)
        {
            if (l + dx[i] < 0 || l + dx[i] > 8) continue;
            if ((l == 3 && dx[i] == -1)||(l == 6 && dx[i] == -1)) continue;
            if ((l == 2 && dx[i] == 1)||(l == 5 && dx[i] == 1)) continue;
            string ne = now, ch = now.substr(l + dx[i], 1);
            ne.replace(l, 1, ch);
            ch = '0';
            ne.replace(l+dx[i], 1, ch);
            int xx=std::atoi(ne.c_str());
            if (!find(xx)) 
            {
                insert(xx);
                t.push(ne);
                state.push(ns + 1);
                if (ne == ed)
                {
                    fl = 1;
                    printf("%d\n", ns + 1);
                    return 0;
                }
            }
        }

    }
}
int main()
{
    for (int i = 1; i <= 9; i++)
    {
        char ch = getchar();
        while (ch < '0' || ch > '8') {ch = getchar();}
        start += ch;
    }
    bfs();
    if (fl == 0) printf("-1");
}

发表于 2017-05-31 21:10:21 in 题解