zoukankan      html  css  js  c++  java
  • hdu.1043.Eight (打表 || 双广 + 奇偶逆序)

    Eight

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 14380    Accepted Submission(s): 4044 Special Judge

    Problem Description
    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as: 
     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15  x
    where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle: 
     1  2  3  4     1  2  3  4     1  2  3  4     1  2  3  4  5  6  7  8     5  6  7  8     5  6  7  8     5  6  7  8  9  x 10 12     9 10  x 12     9 10 11 12     9 10 11 12 13 14 11 15    13 14 11 15    13 14  x 15    13 14 15  x             r->            d->            r->
    The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively. 
    Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and  frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course). 
    In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three  arrangement.
     
    Input
    You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle 
    1 2 3  x 4 6  7 5 8 
    is described by this list: 
    1 2 3 x 4 6 7 5 8
     
    Output
    You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.
     
    Sample Input
    2 3 4 1 5 x 7 6 8
     
    Sample Output
    ullddrurdllurdruldr
      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 #include<ctype.h>
      5 typedef long long ll ;
      6 int map[5][5] ;
      7 char mp[20] ;
      8 int l , r , l1 , r1 ;
      9 int flag ;
     10 int anti ;
     11 int move[][2] = {{1,0} , {-1,0} , {0,1} , {0,-1}} ;
     12 const int mod = 400000 ;
     13 struct node
     14 {
     15     int x , y , nxt ;
     16     int map[3][3] ;
     17 } b[mod];
     18 struct hash
     19 {
     20     ll w , id ;
     21     int nxt ;
     22 }e[mod * 2];
     23 int H[mod * 2] , E ;
     24 
     25 void insert (ll x , int id)
     26 {
     27     int y  = x % mod ;
     28     if (y < 0) y += mod ;
     29     e[++ E].w = x ;
     30     e[E].id = id ;
     31     e[E].nxt = H[y] ;
     32     H[y] = E ;
     33 }
     34 
     35 int find (ll x)
     36 {
     37     int y = x % mod ;
     38     if (y < 0 ) y += mod ;
     39     for (int i = H[y] ; ~ i ; i = e[i].nxt ) {
     40         if (e[i].w == x)
     41             return e[i].id ;
     42     }
     43     return -1 ;
     44 }
     45 
     46 void table ()
     47 {
     48     node ans , tmp ;
     49     E = -1 ;  memset (H , -1 , sizeof (H) ) ;
     50     l1 = 0 , r1= 1 ;
     51     b[l1].x = 2 , b[l1].y = 2 , b[l1].nxt = -1 ;
     52     ll sum = 0 ;
     53     for (int i = 0 ; i < 3 ; i ++) for (int j = 0 ; j < 3 ; j ++) b[l1].map[i][j] = i * 3 + j + 1 ;
     54     insert (123456789 , 0 ) ;
     55     while (l1 != r1) {
     56         ans = b[l1] ;
     57         for (int i = 0 ; i < 4 ; i ++) {
     58             tmp.x = ans.x + move[i][0] ; tmp.y = ans.y + move[i][1] ;
     59             if (tmp.x < 0 || tmp.y < 0 || tmp.x >= 3 || tmp.y >= 3) continue ;
     60             for (int i = 0 ; i < 3 ; i ++) for (int j = 0 ; j < 3 ; j ++) tmp.map[i][j] = ans.map[i][j] ;
     61             std::swap (tmp.map[ans.x][ans.y] , tmp.map[tmp.x][tmp.y]) ;
     62             sum = 0 ;
     63             for (int i = 0 ; i < 3 ; i ++) for (int j = 0 ; j < 3 ; j ++) sum = sum * 10 + tmp.map[i][j] ;
     64             if (find (sum) != -1 ) continue ;
     65             insert (sum  , r1 ) ;
     66             tmp.nxt = l1 ;
     67             b[r1 ++] = tmp ;
     68         }
     69         l1 ++ ;
     70     }
     71 }
     72 
     73 void solve (int u)
     74 {
     75     if (u == -1) return ;
     76     int t = b[u].nxt ;
     77     if (t != -1) {
     78         int x = b[t].x - b[u].x , y = b[t].y - b[u].y ;
     79         if (x == 1) printf ("d") ;
     80         else if (x == -1) printf ("u") ;
     81         else if (y == 1) printf ("r") ;
     82         else if (y == - 1) printf ("l") ;
     83     }
     84     solve (t) ;
     85 }
     86 
     87 int main ()
     88 {
     89     freopen ("a.txt" , "r" , stdin ) ;
     90     table () ;
     91     while (gets (mp) != NULL) {
     92         int tot = 0 ;
     93         for (int i = 0 ; mp[i] != '' ; i ++) {
     94             if (mp[i] != ' ') {
     95                 if (isdigit (mp[i])) {
     96                     map[tot / 3][tot % 3] = mp[i] - '0' ;
     97                 }
     98                 else map[tot / 3][tot % 3] = 9 ;
     99                 tot ++ ;
    100             }
    101         }
    102         ll sum = 0 ;
    103         for (int i = 0 ; i < 3 ; i ++) for (int j = 0 ; j < 3 ; j ++) sum = sum * 10 + map[i][j] ;
    104         anti = find (sum) ;
    105         if (anti != -1) solve (anti) ;
    106         else printf ("unsolvable") ;
    107         puts ("") ;
    108     }
    109     return 0 ;
    110 }
    View Code

    打表思路很简单,也是为了对抗unsolve这种情况,从123456789最终状态产生所有状态,即可.

    奇偶逆序:

    逆序数:也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。

    结论:(是除去移动元素,(这里是9))

    对源状态A与目标状态B进行规范化,使得两矩阵的元素0的位置相同;记为新的源状态A'与目标状态B';
    若A'与B'的逆序对的奇偶性相同(即A'与B1的逆序对的奇偶性相同),则A'必定可能转化为B',即A可以转化到B; 
    若A'与B'的逆序对的奇偶性不同(即A'与B2的逆序对的奇偶性相同),则A'必定不可能转化为B',即A不可以转化到B;

    也就是为了对抗unsolve.

    然后用双广就OK了.

  • 相关阅读:
    结构体怎么组包发送
    开源语音代码eSpeak1.06 的移植到单片机的过程(二)之分析下speak.c 文件
    看看深圳的房价
    开源语音代码eSpeak1.06 的移植到单片机的过程(一)0之分析下espeak.c 文件
    开源语音代码eSpeak1.06 的学习入门
    利尔达模组CAT1 UIS8910指令的 TCP相关中文解释
    将博客搬至CSDN
    【原创】大叔问题定位分享(39)azkaban定期出现fullgc
    【原创】大叔经验分享(129)mac下启动MAT报错
    【原创】大数据基础之Doris(1)编译安装和启动
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4468700.html
Copyright © 2011-2022 走看看