九宫格

#include<bits/stdc++.h>
using namespace std;
//用bfs以为找到一个解就是最优的,类似于走迷宫
//不需要清除hash,因为这就是在状态图上进行bfs,隐式图,没法vis数组
typedef pair<int,string> pp;
const int mod=1000003;
int ans=0x3f3f3f3f,d[][2]={{1,0},{-1,0},{0,1},{0,-1}},n,nx,ny;//不要单独声明
//bool mapper[100000000];//9位数,太大了,bool都不行,只能处理冲突
vector<int> mapper[1000003+7];
string now,to;
queue<pp> q;
//set<pp> se;
//set的速度很慢,需要自己实现hash
int hashh(const char *string1){
    //将字符串准换成整数进行hash
    int rt=0;
    for(int i=0;i<9;i++)
        if(string1[i]!='.') rt=rt*10+string1[i]-'0';
        else rt=rt*10;
    return rt;
}
void set_hash(int x){
    mapper[x%mod].push_back(x);
}
bool get_hash(int x){
    int p=x%mod;
    for(int i=0;i<mapper[p].size();i++){
        if(mapper[p][i]==x) return true;
    }
    return false;
}
int main() {
    cin>>now>>to;
    memset(mapper,0, sizeof(mapper));// 1 设置不方便
    //bfs
    q.push({0,now});
//    se.insert({0,now});
    set_hash(hashh(now.c_str()));
    while(!q.empty()){
        pp s=q.front();
        q.pop();
        if(s.second==to){
            ans=s.first;
            break;
        }
        n=s.second.find('.');
        nx=n/3;ny=n%3;//获得行列坐标!!
        for(int i=0;i<4;i++){
            int nnx=nx+d[i][0],nny=ny+d[i][1];
            if(nnx<0||nnx>2||nny<0||nny>2) continue;
            pp scpy=s;
            scpy.first++;
            swap(scpy.second[n],scpy.second[nnx*3+nny]);//注意坐标转换
            if(!get_hash(hashh(scpy.second.c_str()))){
                //避免重复加入,因为新加入的肯定距离大不是最优
//                se.insert(scpy);
                set_hash(hashh(scpy.second.c_str()));
                q.push(scpy);
            }
        }
    }
    if(ans!=0x3f3f3f3f) cout<<ans<<endl;
    else cout<<-1<<endl;
    return 0;
}

 

posted @ 2020-06-06 21:43  西伯利亚挖土豆  阅读(153)  评论(0编辑  收藏  举报