• 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 }
  • 相关阅读:
    不使用SpringBoot如何将原生Feign集成到Spring中来简化http调用
    干货!从Tomcat执行流程了解jsp是如何被解析的,错误提示是哪里生成的。
    对TCP三次握手四次分手还不清楚的速度进,超简单解析,明白了就很好记!
    SpringCache与redis集成,优雅的缓存解决方案
    高可用的Spring FTP上传下载工具类(已解决上传过程常见问题)
    Hibernate级联之一对多和inverse解析
    Spring的面向切面
    归并排序:步骤讲解与代码实现
    关于操作系统中多个fork()会创建几个进程的理解
    win-sudo插件解决Git bash 执行脚本报错问题 bash: sudo: command not found
  • 原文地址:https://www.cnblogs.com/algorithms/p/2496194.html
Copyright © 2020-2023  润新知