• POJ1077 Eight —— 正向BFS


    主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html



    代码一:以数组充当队列,利用结构体中的pre追溯上一个状态在数组(队列)中的下标:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 #define ms(a,b) memset((a),(b),sizeof((a)))
     13 using namespace std;
     14 typedef long long LL;
     15 const int INF = 2e9;
     16 const LL LNF = 9e18;
     17 const int MOD = 1e9+7;
     18 const int MAXN = 1e6+10;
     19 #define AIM  1     //123456789的哈希值为1
     20 
     21 struct node
     22 {
     23     int status;
     24     int s[9];
     25     int loc;
     26     char path;
     27     int pre;  //pre为上一个操作在队列中的下标,用于输出路径
     28 };
     29 
     30 int vis[MAXN], fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320};
     31 int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 };
     32 char op[4] = {'u', 'd', 'l', 'r'  };
     33 
     34 int cantor(int s[])  //获得哈希函数值
     35 {
     36     int sum = 0;
     37     for(int i = 0; i<9; i++)
     38     {
     39         int num = 0;
     40         for(int j = i+1; j<9; j++)
     41             if(s[j]<s[i])
     42                 num++;
     43         sum += num*fac[8-i];
     44     }
     45     return sum+1;
     46 }
     47 
     48 node que[MAXN];
     49 int front, rear;
     50 int bfs(node now)
     51 {
     52     ms(vis,0);
     53     front = rear = 0;
     54 
     55     now.status = cantor(now.s);
     56     vis[now.status] = 1;
     57     que[rear++] = now;
     58 
     59     node tmp;
     60     while(front!=rear)
     61     {
     62         now = que[front++];
     63         if(now.status==AIM)
     64             return front-1;
     65 
     66         int x = now.loc/3;
     67         int y = now.loc%3;
     68         for(int i = 0; i<4; i++)
     69         {
     70             int xx = x + dir[i][0];
     71             int yy = y + dir[i][1];
     72             if(xx>=0 && xx<=2 && yy>=0 && yy<=2)
     73             {
     74                 tmp = now;
     75                 tmp.s[x*3+y] = tmp.s[xx*3+yy];  //交换位置,下同
     76                 tmp.s[xx*3+yy] = 9;
     77                 tmp.status = cantor(tmp.s);
     78                 if(!vis[tmp.status])
     79                 {
     80                     vis[tmp.status] = 1;
     81                     tmp.loc = xx*3+yy;
     82                     tmp.path = op[i];     //保存操作
     83                     tmp.pre = front-1;  //保存当前结点的状态的上一个状态所在的结点在数组(队列)的下标
     84                     que[rear++] = tmp;
     85                 }
     86             }
     87         }
     88     }
     89     return -1;
     90 }
     91 
     92 void Print(int i)   //利用递归的特点(压栈),输出路径
     93 {
     94     if(i==0) return;    //到了目的状态,则退出。目的状态的结点在数组(队列)中的下标为0
     95     Print(que[i].pre);  //访问上一步
     96     putchar(que[i].path); //输出操作
     97 }
     98 
     99 int main()
    100 {
    101     char tmp[50];
    102     while(gets(tmp))
    103     {
    104         node beg;
    105         int cnt = 0;
    106         for(int i = 0; tmp[i]; i++)
    107         {
    108             if(tmp[i]==' ') continue;
    109             if(tmp[i]=='x') beg.s[cnt] = 9, beg.loc = cnt++;
    110             else  beg.s[cnt++] = tmp[i]-'0';
    111 
    112         }
    113         int i = bfs(beg);
    114         if(i==-1)
    115             puts("unsolvable");
    116         else
    117             Print(i), putchar('
    ');
    118     }
    119 }
    View Code

    代码二(推荐):把pre和path放在结构体外,利用当前状态status追溯上一个状态status:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 #define ms(a,b) memset((a),(b),sizeof((a)))
     13 using namespace std;
     14 typedef long long LL;
     15 const int INF = 2e9;
     16 const LL LNF = 9e18;
     17 const int MOD = 1e9+7;
     18 const int MAXN = 1e6+10;
     19 #define AIM  1     //123456789的哈希值为1
     20 
     21 struct node
     22 {
     23     int status;
     24     int s[9];
     25     int loc;
     26 };
     27 
     28 int vis[MAXN], fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320};
     29 int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 };
     30 char op[4] = {'u', 'd', 'l', 'r'  };
     31 char path[MAXN];
     32 int pre[MAXN];
     33 
     34 int cantor(int s[])  //获得哈希函数值
     35 {
     36     int sum = 0;
     37     for(int i = 0; i<9; i++)
     38     {
     39         int num = 0;
     40         for(int j = i+1; j<9; j++)
     41             if(s[j]<s[i])
     42                 num++;
     43         sum += num*fac[8-i];
     44     }
     45     return sum+1;
     46 }
     47 
     48 queue<node>que;
     49 bool bfs(node now)
     50 {
     51     ms(vis,0);
     52     while(!que.empty()) que.pop();
     53 
     54     now.status = cantor(now.s);
     55     pre[now.status] = -1;   //开始状态的上一个状态为-1,用于输出路径时“刹车”
     56     vis[now.status] = 1;
     57     que.push(now);
     58 
     59     node tmp;
     60     while(!que.empty())
     61     {
     62         now = que.front();
     63         que.pop();
     64         if(now.status==AIM) //找到了123456789的状态
     65             return true;
     66 
     67         int x = now.loc/3;
     68         int y = now.loc%3;
     69         for(int i = 0; i<4; i++)
     70         {
     71             int xx = x + dir[i][0];
     72             int yy = y + dir[i][1];
     73             if(xx>=0 && xx<=2 && yy>=0 && yy<=2)
     74             {
     75                 tmp = now;
     76                 tmp.s[x*3+y] = tmp.s[xx*3+yy];  //交换位置,下同
     77                 tmp.s[xx*3+yy] = 9;
     78                 tmp.status = cantor(tmp.s);
     79                 if(!vis[tmp.status])
     80                 {
     81                     vis[tmp.status] = 1;
     82                     tmp.loc = xx*3+yy;
     83                     pre[tmp.status] = now.status;   //tmp.status的上一个状态为now.status
     84                     path[tmp.status] = op[i];   //保存操作
     85                     que.push(tmp);
     86                 }
     87             }
     88         }
     89     }
     90     return 0;
     91 }
     92 
     93 void Print(int status)
     94 {
     95     if(pre[status]==-1) return;
     96     Print(pre[status]);     //追溯上一个状态
     97     putchar(path[status]);
     98 }
     99 
    100 int main()
    101 {
    102     char str[50];
    103     while(gets(str))
    104     {
    105         node now;
    106         int cnt = 0;
    107         for(int i = 0; str[i]; i++)
    108         {
    109             if(str[i]==' ') continue;
    110             if(str[i]=='x') now.s[cnt] = 9, now.loc = cnt++;
    111             else  now.s[cnt++] = str[i]-'0';
    112         }
    113         if(!bfs(now))
    114             puts("unsolvable");
    115         else
    116             Print(AIM), putchar('
    ');
    117     }
    118 }
    View Code


  • 相关阅读:
    (转载)显示调用构造函数和析构函数
    (转载)c库不正确问题
    (转载)LINUX UNBUNTU10.04 下 搭建OC编译环境
    (转载)Chrome 快捷键 整理版
    (转载)php循环检测目录是否存在并创建(循环创建目录)
    (转载)PHP 判断常量,变量和函数是否存在
    Dockerfile 指令
    JavaEE&Docker 容器示例
    docker 中运行 redis 服务
    docker 中运行 sshd 服务
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538587.html
Copyright © 2020-2023  润新知