[IDA*模板] POJ 1077 Eight

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cctype>
#include <string>
#include <map>
using namespace std;

#define RG register int
#define LL long long
#define abs(x) (x>=0?x:-(x))

string Path,FinalAns;
char Dir[4]={'u','d','l','r'};
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int G[9];

inline int h(){
    int Res=0;
    for(RG i=0;i<9;++i){
        if(G[i]==0) continue;
        Res+=abs(i/3-(G[i]-1)/3)+abs(i%3-(G[i]-1)%3);
    }
    return Res;
}

bool Maintain(int dir){
    int px,py;
    for(RG i=0;i<9;++i)
        if(G[i]==0){px=i/3;py=i%3;break;}
    int nx=px+dx[dir],ny=py+dy[dir];
    if(nx<0||nx>2||ny<0||ny>2) return false;
    swap(G[px*3+py],G[nx*3+ny]);
    return true;
}

pair<bool,int> IDA(int deep,int bound){
    int hv=h();
    if(hv==0){FinalAns=Path;return make_pair(true,deep);}
    if(deep+hv>bound) return make_pair(false,deep+hv);
    int next_bound=1000;
    pair<bool,int> Res;
    for(int i=0;i<4;++i){
        if(!Maintain(i)) continue;
        Path.push_back(Dir[i]);
        Res=IDA(deep+1,bound);
        Maintain(i^1);
        Path.erase(Path.end()-1);
        if(Res.first) return Res;
        if(Res.second<next_bound) next_bound=Res.second;
    }
    return make_pair(false,next_bound);
}

int main(){
    ios::sync_with_stdio(false);
    for(RG i=0;i<9;++i){
        char x;cin>>x;
        if(isdigit(x)) G[i]=x-'0';
        else G[i]=0;
    }
    pair<bool,int> Ans=make_pair(false,h());
    while(!Ans.first)
        Ans=IDA(0,Ans.second);
    cout<<FinalAns<<endl;
    return 0;
}
posted @ 2020-04-06 13:25  AE酱  阅读(141)  评论(0编辑  收藏  举报