• 【POJ1077】八数码


    这道题是洛谷“八数码难题”的升级版,洛谷只要求出最少步数,而本题要输出结果。

    我们在搜索的时候记录每一个状态的前驱,最后输出的时候递归即可。

    我们采用A*算法进行搜索,设计估价函数为当前状态每个点与目标状态每个点的曼哈顿距离之和。在搜索时建立一个小根堆维护即可。

    代码细节比较多,注意对细节的处理。可以用pair,map简化部分代码。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <map>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <cmath>
      8 using namespace std;
      9 struct node {
     10     int val,dis;
     11     bool operator <(const node &x) const {
     12         return dis>x.dis;
     13     }
     14 };
     15 priority_queue<node> q;
     16 map<int,int> dis,fa,go;
     17 const int fx[4]={-1,0,0,1};
     18 const int fy[4]={0,-1,1,0};
     19 char dir[4]={'u','l','r','d'};
     20 int a[4][4];
     21 int calc(int a[4][4]) {
     22     int ret=0;
     23     for(int i=1;i<=3;i++)
     24         for(int j=1;j<=3;j++)
     25             ret=ret*9+a[i][j];
     26     return ret;
     27 }
     28 int value(int a[4][4]) {
     29     int ret=0;
     30     for(int i=1;i<=3;i++)
     31         for(int j=1;j<=3;j++) {
     32             if(a[i][j]==0) continue ;
     33             int x=(a[i][j]-1)/3+1;
     34             int y=(a[i][j]-1)%3+1;
     35             ret+=abs(i-x)+abs(j-y);
     36         }
     37     return ret;
     38 }
     39 pair<int,int> recalc(int val,int a[4][4]) {
     40     int x,y;
     41     for(int i=3;i>=1;i--)
     42         for(int j=3;j>=1;j--) {
     43             a[i][j]=val%9;
     44             val/=9;
     45             if(!a[i][j]) x=i,y=j;
     46         }
     47     return make_pair(x,y);
     48 }
     49 int bfs(int x,int y,int endval) {
     50     int st=calc(a);
     51     dis[st]=0;
     52     q.push(node{st,value(a)});
     53     while(!q.empty()) {
     54         int now=q.top().val;
     55         q.pop();
     56         if(now==endval) return dis[now];
     57         int a[4][4];
     58         pair<int,int> k=recalc(now,a);
     59         int nowx=k.first;
     60         int nowy=k.second;
     61         for(int i=0;i<4;i++) {
     62             int xx=nowx+fx[i];
     63             int yy=nowy+fy[i];
     64             if(xx<1||xx>3||yy<1||yy>3) continue ;
     65             swap(a[nowx][nowy],a[xx][yy]);
     66             int neww=calc(a);
     67             if(dis.find(neww)==dis.end()||dis[neww]>dis[now]+1) {
     68                 dis[neww]=dis[now]+1;
     69                 fa[neww]=now;
     70                 go[neww]=i;
     71                 q.push(node{neww,dis[neww]+value(a)});
     72             }
     73             swap(a[nowx][nowy],a[xx][yy]);
     74         }
     75     }
     76     return -1;
     77 }
     78 void print(int val) {
     79     if(fa.find(val)==fa.end()) return ;
     80     print(fa[val]);
     81     putchar(dir[go[val]]);
     82 }
     83 int main() {
     84     int end=0;
     85     for(int i=1;i<=8;i++)
     86         end=end*9+i;
     87     end*=9;
     88     int sx,sy;
     89     for(int i=1;i<=3;i++)
     90         for(int j=1;j<=3;j++) {
     91             char s[2];
     92             scanf("%s",s);
     93             if(s[0]=='x') a[i][j]=0,sx=i,sy=j;
     94             else a[i][j]=s[0]-'0';
     95         }
     96     int ans=bfs(sx,sy,end);
     97     if(ans==-1) puts("unsolvable");
     98     else print(end);
     99     return 0;
    100 }
    AC Code
  • 相关阅读:
    [tp3.2.1]sql查询语句(一)
    [crunch bang]在Crunch Bang安装和设置fcitx(小企鹅输入法)
    [tp3.2.1]大D构建模型
    [tp3.2.1]数据模型
    [tp3.2.1]开启URL(重写模式),省略URL中的index.php
    [tp3.2.1]让默认页面: 加载Home模块的Index控制器;而让admin.php默认去加载Admin模块的Adminc控制器.
    [JAVA]在linux中设置JDK环境,ZendStudio,Eclipse
    [fedora21]给fedora21安装fcitx输入法
    Software--Architecture--Design DataAccess 数据访问
    leetcode--Algorithm--Array_Part 1 Easy- 566 Reshape the Matrix
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10630412.html
Copyright © 2020-2023  润新知