zoukankan      html  css  js  c++  java
  • Hdu 1043 Eight (八数码问题)

    题目链接:

      http://acm.hdu.edu.cn/showproblem.php?pid=1043

    题目描述:

      3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动到12345678x的状态?

      hint:每一个3*3的格子从上到右,从左到右,一行一行读。

    解题思路:

      比较简单的八数码问题,大一暑假老师讲过,一直手懒脑懒并没有亲自尝试过。因为是多实例,先从12345678x的状态bfs出来所有可以到达的状态,并且记录下来路径。八数码最重要的就是保存状态,如果这个题目用十进制保存状态的话,至少要到达10^9的数量级。可以利用康拓展开hash搜索到的状态,空间可以缩小到9!(ง •̀_•́)ง

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <string>
      4 #include <queue>
      5 #include <iostream>
      6 #include <algorithm>
      7 using namespace std;
      8 
      9 #define maxn 370000
     10 struct node
     11 {
     12     string path;//路径
     13     int s[10];  //state
     14     int loc;    //9的位置
     15     int ct;     //康拓hash
     16 };
     17 int fac[10] = {1, 1, 2, 6, 24, 120, 720, 720*7, 720*7*8, 720*7*8*9};
     18 //0!,1!,2!....9!
     19 int dir[4][2] = {0,1, 0,-1, -1,0, 1,0}; // r, l, u, d
     20 int vis[maxn];
     21 char di[5] = "lrdu"; //l, r, d, u
     22 string path[maxn];
     23 void init ()
     24 {
     25     memset (vis, 0, sizeof(vis));
     26 }
     27 
     28 int cantor (int a[]) //康拓hash
     29 {
     30     int sum = 0;
     31     for (int i=0; i<9; i++)
     32     {
     33         int m = 0;
     34         for (int j=i+1; j<9; j++)
     35             if (a[j] < a[i])
     36                 m ++;
     37             sum += m * (fac[9-i-1]);
     38     }
     39     return sum + 1;
     40 }
     41 
     42 void bfs ()
     43 {
     44     node cur, next;
     45     queue <node> Q;
     46 
     47     for(int i=0; i<8; i++)
     48         cur.s[i] = i + 1;
     49     cur.s[8] = 0;
     50     cur.ct = cantor (cur.s);
     51     cur.loc = 8;
     52 
     53     Q.push (cur);
     54     vis[cur.ct] = 1;
     55     path[cur.ct] = "";
     56 
     57     while (!Q.empty())
     58     {
     59         cur = Q.front();
     60         Q.pop ();
     61 
     62         for (int i=0; i<4; i++)
     63         {
     64             int x = cur.loc / 3 + dir[i][0];
     65             int y = cur.loc % 3 + dir[i][1];
     66             if (x<0 || x>2 || y<0 || y>2)
     67                 continue;
     68             next = cur;
     69             next.loc = x * 3 + y;
     70             next.s[cur.loc] = next.s[next.loc];
     71             next.s[next.loc] = 0;
     72             next.ct = cantor (next.s);
     73             if (!vis[next.ct])
     74             {
     75                 vis[next.ct] = 1;
     76                 path[next.ct] = di[i] + path[cur.ct];
     77                 Q.push (next);
     78             }
     79         }
     80     }
     81 
     82 }
     83 
     84 int main ()
     85 {
     86     init ();
     87     bfs ();
     88     char s[2];
     89     int a[10];
     90 
     91     while (scanf ("%s", s) != EOF)
     92     {
     93         if (s[0] == 'x')
     94             a[0] = 0;
     95         else
     96             a[0] = s[0] - '0';
     97 
     98         for (int i=1; i<9; i++)
     99         {
    100             scanf ("%s", s);
    101             if (s[0] == 'x')
    102                 a[i] = 0;
    103             else
    104                 a[i] = s[0] - '0';
    105         }
    106         int m = cantor (a);
    107         if (vis[m])
    108             cout<<path[m]<<endl;
    109         else
    110             puts ("unsolvable");
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    列表的创建02
    python如何设置注释模板,文件模板
    python语言使用rsa密码算法对数据加密时不能对中文加密问题的解决
    python编码解码,字符数据转换问题(自学笔记)
    字符串与数组之间的互相转换
    vc++文本编辑
    OCP 062【中文】考试题库(cuug内部资料)第28题
    OCP 062【中文】考试题库(cuug内部资料)第27题
    OCP 062【中文】考试题库(cuug内部资料)第26题
    OCP 062【中文】考试题库(cuug内部资料)第25题
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/5360213.html
Copyright © 2011-2022 走看看