hdu1043 Eight

A*算法 f(n)=g(n)+h(n)

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
int aim=1,vis[1000000];
int nxt[4][2]={-1,0,1,0,0,-1,0,1};
int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
char index[5]="udlr";
int cantor(int s[])
{
    int sum=0;
    for(int i=0;i<9;i++){
        int num=0;
        for(int j=i+1;j<9;j++)
            if(s[j]<s[i]) num++;
        sum+=(num*fac[9-i-1]);
    }
    return sum+1;
}

int get_h(int *a)
{
   int sum=0;
   for(int i=0;i<9;i++)
       sum+=abs(a[i]-i-1);
   return sum;
}

struct node
{
    string path;
    int loc;
    int g,h;
    int s[9];
    int key;
    bool operator < (const node&o)const{
        return g+h>o.g+o.h;
    }
};

priority_queue<node>que;
node fir;
bool check(int *a)
{
   int sum=0;
   for(int i=0;i<8;i++){
       if(a[i]==9) continue;
     for(int j=i+1;j<9;j++){
        if(a[j]==9) continue;
        if(a[i]>a[j]) sum++;
     }
   }
   return sum%2 ? false : true;
}

void bfs()
{
    memset(vis,0,sizeof(vis));
    while(!que.empty()) que.pop();
    fir.key=cantor(fir.s);
    fir.g=0;
    fir.h=get_h(fir.s);
    vis[fir.key]=1;
    que.push(fir);
    while(!que.empty()){
        node cur=que.top();
        que.pop();
       // cout<<cur.key<<endl;
        if(cur.key==aim){
            cout<<cur.path<<endl;
            return;
        }
        int x=cur.loc/3;
        int y=cur.loc%3;
        for(int i=0;i<4;i++){
            int tx=x+nxt[i][0];
            int ty=y+nxt[i][1];
            if(tx<0||ty<0||tx>2||ty>2) continue;
            node Nxt=cur;
            Nxt.loc=tx*3+ty;
            Nxt.s[cur.loc]=Nxt.s[Nxt.loc];
            Nxt.s[Nxt.loc]=9;
            Nxt.key=cantor(Nxt.s);
            Nxt.g+=1;
            Nxt.h=get_h(Nxt.s);
            if(!vis[Nxt.key]){
                vis[Nxt.key]=1;
                Nxt.path=Nxt.path+index[i];
                if(Nxt.key==aim)
                {
                    cout<<Nxt.path<<endl;
                    return;
                }
                que.push(Nxt);
            }
        }
    }
}
int main()
{
   char ch[2];
   while(~scanf("%s",ch)){
      if(ch[0]=='x'){ fir.s[0]=9; fir.loc=0; }
      else{ fir.s[0]=ch[0]-'0';}
      for(int i=1;i<9;i++){
          scanf("%s",ch);
          if(ch[0]=='x'){ fir.s[i]=9; fir.loc=i;}
          else{ fir.s[i]=ch[0]-'0';}
      }
      if(!check(fir.s)) printf("unsolvable\n");
      else bfs();
   }
   return 0;
}

你可能感兴趣的:(hdu1043 Eight)