POJ1077(Eight)

题目链接

经典的8数码问题,不要求是最少步数。

View Code
  1 #include <stdio.h>

  2 #include <string.h>

  3 #include <queue>

  4 #define N 362881

  5 #define ABS(x) ((x)>0?(x):(-(x)))

  6 using namespace std;

  7 const int dx[4]={0,0,1,-1};

  8 const int dy[4]={1,-1,0,0};

  9 char DIR[4]={'r','l','d','u'};

 10 const int pow10[10]={1,10,100,1000,10000,

 11                       100000,1000000,10000000,

 12                       100000000,1000000000};

 13 typedef pair<int,int> node;

 14 priority_queue<node,vector<node>,greater<node> > pq;

 15 int s,t=123456780,tp=123456870;

 16 int tx[9]={2,0,0,0,1,1,1,2,2},ty[9]={2,0,1,2,0,1,2,0,1};

 17 int fact[9];

 18 int f[N],g[N],z[N],dir[N],p[N];

 19 char vis[N];

 20 int h(int k)

 21 {

 22   int i,x,y,ai,ret=0;

 23   for(x=0;x<3;x++)

 24   {

 25     for(y=0;y<3;y++)

 26     {

 27       i=8-3*x-y;

 28       ai=k/pow10[i]%10;

 29       ret+=ABS(tx[ai]-x)+ABS(ty[ai]-y);

 30     }

 31   }

 32   return ret;

 33 }

 34 int hash(int k)

 35 {

 36   int i,j,ai,aj,cnt,ret=0,zero=8;

 37   for(i=8;i>0;i--)

 38   {

 39     ai=k/pow10[i]%10;

 40     if(ai==0) zero=8-i;

 41     cnt=0;

 42     for(j=i-1;j>=0;j--)

 43     {

 44       aj=k/pow10[j]%10;

 45       if(aj<ai) cnt++;

 46     }

 47     ret+=cnt*fact[i];

 48   }

 49   z[ret]=zero;

 50   return ret;

 51 }

 52 bool read_case()

 53 {

 54   int i,cnt=0;

 55   char c;

 56   s=0;

 57   while(cnt<9)

 58   {

 59     if(scanf("%c",&c)==EOF)  return false;

 60     if(c>='1' && c<='8' || c=='x')

 61     {

 62       cnt++;

 63       c=(c=='x'?'0':c);

 64       s=s*10+c-'0';

 65     }

 66   }

 67   return true;

 68 }

 69 int move(int k,int pos,int d)

 70 {

 71   int i,j,ni,nj,npos,a;

 72   i=pos/3;

 73   j=pos%3;

 74   ni=i+dx[d];

 75   nj=j+dy[d];

 76   if(ni<0 || nj<0 || ni>=3 || nj>=3) return -1;

 77   npos=ni*3+nj;

 78   a=k/pow10[8-npos]%10;

 79   return k+a*(pow10[8-pos]-pow10[8-npos]);

 80 }

 81 void print(int k)

 82 {

 83   if(p[k]==-1)  return;

 84   print(p[k]);

 85   printf("%c",DIR[dir[k]]);

 86 }

 87 void process()

 88 {

 89   int u,v,uu,vv,d;

 90   node tmp;

 91   memset(vis,0,sizeof(vis));

 92   while(!pq.empty())  pq.pop();

 93   u=s;

 94   uu=hash(u);

 95   p[uu]=-1;

 96   vis[uu]=1;

 97   f[uu]=0;

 98   g[uu]=f[uu]+h(u);

 99   pq.push(make_pair(g[uu],u));

100   while(!pq.empty())

101   {

102     tmp=pq.top(),pq.pop();

103     u=tmp.second;    

104     uu=hash(u);

105     vis[uu]++;

106     if(u==t || u==tp)  break;

107     for(d=0;d<4;d++)

108     {

109       v=move(u,z[uu],d);

110       if(v==-1) continue;

111       vv=hash(v);

112       if(vis[vv]==2)  continue;

113       if(vis[vv]==1 && f[uu]+1<f[vv])

114       {

115         g[vv]+=f[uu]+1-f[vv];

116         f[vv]=f[uu]+1;

117         p[vv]=uu;

118         dir[vv]=d;

119       }

120       else

121       {

122         f[vv]=f[uu]+1;

123         g[vv]=f[vv]+h(v);

124         pq.push(make_pair(g[vv],v));

125         vis[vv]++;

126         p[vv]=uu;

127         dir[vv]=d;

128       }

129     }

130   }

131   if(vis[hash(t)]!=2) puts("unsolvable");

132   else print(hash(t)),printf("\n");

133 }

134 int main()

135 {

136   int i;

137   fact[0]=1;

138   for(i=1;i<9;i++)  fact[i]=fact[i-1]*i;

139   while(read_case())  process();

140   return 0;

141 }

 

你可能感兴趣的:(poj)