zoukankan      html  css  js  c++  java
  • HDU 1043 Eight(八数码)

    HDU 1043 Eight(八数码)

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

     

    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:
    15-puzzle有着超过100年的历史;就算没听过,估计也见过。它由15片滑块组成,各块标有数字1到15,并且全都装在一个4 x 4的边框里,防止哪块突然丢了。空块为’x’;这道题的目标是排列滑块使之顺序如下:
    CN
     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:

    唯一的合法操作是将’x’与其共边的滑块交换。例子如下,通过一系列移动解决一个被稍微打乱的问题。
    CN
     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.

    上一行的字母表示每次’x’与哪块相邻的滑块交换;有效值'r''l''u''d'分别表示右、左、上、下。
    
    并非所有情况都有解;在1870年,一个叫Sam Loyd的人就以发布了一个无解版本而出名,成功地难住了许多人。实际上,要制造无解的情况只需交换两个滑块(当然是非’x’滑块)。
    
    这个问题中,你需要写个程序解决著名的八数码问题,滑块为三行三列。
    CN
    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

    你会得到若干个八数码的配置描述。每个描述都是一个滑块初始位置的列表,从上往下,从左往右,使用数字1到8,还有’x’表示。比如,
    
    1 2 3 
    x 4 6 
    7 5 8 
    
    描述如下:
    
    1 2 3 x 4 6 7 5 8
    CN


    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.
    如果无解,输出”unsolvable''”,否则输出一个仅由'r', 'l', 'u''d' 组成的字符串,描述求解的步骤。这个字符串不含空格且单独在一行。用例间别输出空行。
    CN

    Sample Input - 输入样例

    2  3  4  1  5  x  7  6  8
    

     

    Sample Output - 输出样例

    ullddrurdllurdruldr
    

     

    题解
      逼你学新知识系列……(某废渣作死爆内存了……)
      状态可以用全排列表示,用康托展开来压缩状态和去重,然后剩下的只有BFS了……(无聊用了树状数组求逆序数)
      多组输入有点坑……其实如果符合情况直接输出空行也是可以的。

     

    代码 C++

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #define MX 362880
     5 #define bitMX 10
     6 
     7 int tre[bitMX];
     8 int lowBit(int a) { return -a&a; }
     9 void add(int i) {
    10     while (i < bitMX) { ++tre[i]; i += lowBit(i); }
    11 }
    12 int sum(int i) {
    13     int opt = 0;
    14     while (i) { opt += tre[i]; i -= lowBit(i); }
    15     return opt;
    16 }
    17 
    18 int ktf[9], data[9];
    19 int preKte() {
    20     int i, j, opt = 0;
    21     memset(tre, 0, sizeof tre);
    22     for (i = 8; ~i; --i) {
    23         opt += sum(data[i])*ktf[i];
    24         add(data[i]);
    25     }
    26     return opt;
    27 }
    28 void kte(int a) {
    29     int i, j, tmp[9];
    30     for (i = 0; i < 9; ++i) tmp[i] = i + 1;
    31     for (i = 0; i < 8; ++i) {
    32         j = a / ktf[i]; a %= ktf[i];
    33         data[i] = tmp[j];
    34         memcpy(tmp + j, tmp + j + 1, sizeof(int)*(8 - j));
    35     }
    36     data[i] = tmp[0];
    37 }
    38 
    39 int lst[MX];
    40 char pre[MX];
    41 void push(int now, int i, int j, char c, std::queue<int> &q) {
    42     data[i] ^= data[j]; data[j] ^= data[i]; data[i] ^= data[j];
    43     int nxt = preKte();
    44     if (!pre[nxt]) {
    45         lst[nxt] = now; pre[nxt] = c;
    46         q.push(nxt);
    47     }
    48     data[i] ^= data[j]; data[j] ^= data[i]; data[i] ^= data[j];
    49 }
    50 void init() {
    51     int i, j, now, nxt;
    52     ktf[7] = 1;
    53     for (i = 6, j = 2; ~i; --i, ++j) ktf[i] = ktf[i + 1] * j;
    54     memset(lst, -1, sizeof lst);
    55     lst[0] = 0; pre[0] = ' ';
    56     std::queue<int> q; q.push(0);
    57     while (!q.empty()) {
    58         now = q.front(); q.pop();
    59         kte(now);
    60         for (i = 0; data[i] != 9; ++i);
    61         if (i > 2) push(now, i, i - 3, 'd', q);
    62         if (i < 6) push(now, i, i + 3, 'u', q);
    63         if (i % 3) push(now, i, i - 1, 'r', q);
    64         if ((i + 1) % 3) push(now, i, i + 1, 'l', q);
    65     }
    66 
    67     
    68 }
    69 int main() {
    70     init();
    71     int i, j;
    72     char red[18];
    73     while (gets(red)) {
    74         for (i = j = 0; i < 18; i += 2, ++j) data[j] = red[i] == 'x' ? 9 : red[i] - '0';
    75         if (~lst[i = preKte()]) {
    76             for (j = i; j; j = lst[j]) putchar(pre[j]);
    77             puts("");
    78         }
    79         else puts("unsolvable");
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    Android 解决小米手机Android Studio安装app 报错的问题It is possible that this issue is resolved by uninstalling an existi
    Android Unresolved Dependencies
    Android studio 自定义打包apk名
    Android Fragment与Activity交互的几种方式
    魅族和三星Galaxy 5.0webView 问题Android Crash Report
    Android几种常见的多渠道(批量)打包方式介绍
    Android批量打包 如何一秒内打完几百个apk渠道包
    上周热点回顾(9.30-10.6)团队
    上周热点回顾(9.23-9.29)团队
    上周热点回顾(9.16-9.22)团队
  • 原文地址:https://www.cnblogs.com/Simon-X/p/6701038.html
Copyright © 2011-2022 走看看