zoukankan      html  css  js  c++  java
  • 1077 Eight

    Eight
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 37738   Accepted: 15932   Special Judge

    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 a description of a configuration of the 8 puzzle. The 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.

    Sample Input

     2  3  4  1  5  x  7  6  8 

    Sample Output

    ullddrurdllurdruldr

    Source

     
    年轻人的第一道A* 答案可能多解
    我的这个程序输入样例输入得到的输出是 ldruullddrurdllurrd
    跟样例输出不一样 搞的我郁闷了半天
     
    注意方向的选取 还有位置的选择
    它是
    1 2 3
    4 5 6
    7 8 9
     
    康拓展开
    类似哈希 给定一个排列组合的数  如123456789 怎么去判定有没有遍历过这个数 可以用康拓展开 八数码问题有9位 直接开1e9的数组可能爆内存 并且有很多数字是用不到的 因为每个数字只出现一次 可能会有123456789 但是绝对不会出现123456788 以此类推 这样浪费了很多空间
    由此引出康拓展开 由这个数是第几小的数来作表示 对N个不同的数的排列组合 一共有N!种排列组合 他们的大小都不一样 所以只需要N!的空间就足够存放所有的状态
    要注意自己定义的康拓的范围
    其中 递增顺序排列是最小的数 即123456789  987654321是最大的数
    我这里写的是goal = 1,  所以 cantor是返回v+1避免出现0, 要是 goal = 0, 则cantor返回v就行了 以此类推
    记忆方法: 只要记住顺序排列是最小的 它的v是最小的 在以下代码片中要让return v+1 等于1 容易知道下划线部分应该填  ar[j] < ar[i]
    int contor(int ar[]) {
        int v = 0;
        for (int i = 0; i < 9; i++) {
            int num = 0;
            for (int j = i + 1; j < 9; j++) {
                if (_______) num++;
            }
            v += num * fac[8 - i];
        }
        return v + 1;
    }
     
    还有个注意点是曼哈顿距离不算x点
    短即是正义 我短我骄傲
      1 #include <stdio.h>
      2 #include <queue>
      3 #include <algorithm>
      4 using namespace std;
      5 int fac[10];
      6 int dx[4] = {-1, 1, 0, 0};
      7 int dy[4] = {0,  0, 1, -1};
      8 char d[4] = {'u','d','r','l'};
      9 const int goal = 1, maxv = 4e5;
     10 bool vis[maxv];
     11 int pre[maxv];
     12 char dir[maxv];
     13 int dish(int ar[]) {
     14     int dis = 0;
     15     for (int i = 0; i < 9; i++) {
     16         if (ar[i] == 9) continue;
     17         int v = ar[i] - 1;
     18         int rx = i / 3, ry = i % 3;
     19         int x = v / 3, y = v % 3;
     20         dis += abs(x - rx) + abs(ry - y);
     21     }
     22     return dis;
     23 }
     24 int contor(int ar[]) {
     25     int v = 0;
     26     for (int i = 0; i < 9; i++) {
     27         int num = 0;
     28         for (int j = i + 1; j < 9; j++)  if (ar[j] < ar[i]) num++;
     29         
     30         v += num * fac[8 - i];
     31     }
     32     return v + 1;
     33 }
     34 struct node {
     35     int g, h, f, sta, xpos;
     36     int s[9];
     37     void init() {
     38         g++; h=dish(s); f=h+g; sta=contor(s);
     39     }
     40     bool operator < (const node x)const {
     41         return f > x.f;
     42     }
     43 };
     44 priority_queue<node> q;
     45 bool Astar(node now) {
     46     fill(vis, vis + maxv, 0);
     47     while (!q.empty()) q.pop();
     48     now.g = -1;
     49     now.init();
     50     q.push(now);
     51     pre[now.sta] = -1;
     52     vis[now.sta] = 1;
     53     while (!q.empty()){
     54         now = q.top(); q.pop();
     55         if (now.sta == goal) return true;
     56         int xpos = now.xpos;
     57         int x = xpos / 3, y = xpos % 3;
     58         for (int i = 0; i < 4; i++) {
     59             int tx = x + dx[i];
     60             int ty = y + dy[i];
     61             if (tx < 0 || ty < 0 || tx >= 3 || ty >= 3) continue;
     62             int newp = tx * 3 + ty;
     63             node tp = now;
     64             tp.xpos = newp;
     65             swap(tp.s[newp], tp.s[xpos]);
     66             tp.init();
     67             
     68             if (vis[tp.sta]) continue;
     69             vis[tp.sta] = 1;
     70             pre[tp.sta] = now.sta;
     71             dir[tp.sta] = d[i];
     72             q.push(tp);
     73         }
     74     }
     75     return false;
     76 }
     77 void Print(int sta) {
     78     if (pre[sta] == -1) return;
     79     Print(pre[sta]);
     80     printf("%c", dir[sta]);
     81 }
     82 int main() {
     83     fac[0] = 1;
     84     for (int i = 1; i < 10; i++) fac[i] = i * fac[i - 1];
     85     char str[30];
     86     while (gets(str)) {
     87         int cnt = 0;
     88         node now;
     89         for (int i = 0; str[i]; i++) {
     90             if (str[i] == ' ') continue;
     91             if (str[i] == 'x') {
     92                 now.xpos = cnt;
     93                 now.s[cnt++] = 9;
     94             }
     95             else
     96                 now.s[cnt++] = str[i] - '0';
     97         }
     98         if (Astar(now)) Print(goal);
     99         else printf("unsolvable");
    100         printf("
    ");
    101     }
    102     return 0;
    103 }
     
  • 相关阅读:
    HybridAPP开发框架Ionic+AngularJS+Cordova搭建
    MySQL数据类型DECIMAL用法
    RabbitMQ用户管理
    Linux中Mysql root用户看不到mysql库问题解决方式
    RabbitMQ环境安装
    RabbitMQ简介
    Mysql根据一个基库生成其他库与其不同的库升级脚本
    关于中文乱码的解决方法(URL方式)
    java反射机制
    the jar file rt.jar has no source attachment
  • 原文地址:https://www.cnblogs.com/smatrchen/p/10594723.html
Copyright © 2011-2022 走看看