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:
-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’表示。比如,

x   

描述如下:

   x     

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++

 #include <cstdio>
#include <cstring>
#include <queue>
#define MX 362880
#define bitMX 10 int tre[bitMX];
int lowBit(int a) { return -a&a; }
void add(int i) {
while (i < bitMX) { ++tre[i]; i += lowBit(i); }
}
int sum(int i) {
int opt = ;
while (i) { opt += tre[i]; i -= lowBit(i); }
return opt;
} int ktf[], data[];
int preKte() {
int i, j, opt = ;
memset(tre, , sizeof tre);
for (i = ; ~i; --i) {
opt += sum(data[i])*ktf[i];
add(data[i]);
}
return opt;
}
void kte(int a) {
int i, j, tmp[];
for (i = ; i < ; ++i) tmp[i] = i + ;
for (i = ; i < ; ++i) {
j = a / ktf[i]; a %= ktf[i];
data[i] = tmp[j];
memcpy(tmp + j, tmp + j + , sizeof(int)*( - j));
}
data[i] = tmp[];
} int lst[MX];
char pre[MX];
void push(int now, int i, int j, char c, std::queue<int> &q) {
data[i] ^= data[j]; data[j] ^= data[i]; data[i] ^= data[j];
int nxt = preKte();
if (!pre[nxt]) {
lst[nxt] = now; pre[nxt] = c;
q.push(nxt);
}
data[i] ^= data[j]; data[j] ^= data[i]; data[i] ^= data[j];
}
void init() {
int i, j, now, nxt;
ktf[] = ;
for (i = , j = ; ~i; --i, ++j) ktf[i] = ktf[i + ] * j;
memset(lst, -, sizeof lst);
lst[] = ; pre[] = ' ';
std::queue<int> q; q.push();
while (!q.empty()) {
now = q.front(); q.pop();
kte(now);
for (i = ; data[i] != ; ++i);
if (i > ) push(now, i, i - , 'd', q);
if (i < ) push(now, i, i + , 'u', q);
if (i % ) push(now, i, i - , 'r', q);
if ((i + ) % ) push(now, i, i + , 'l', q);
} }
int main() {
init();
int i, j;
char red[];
while (gets(red)) {
for (i = j = ; i < ; i += , ++j) data[j] = red[i] == 'x' ? : red[i] - '';
if (~lst[i = preKte()]) {
for (j = i; j; j = lst[j]) putchar(pre[j]);
puts("");
}
else puts("unsolvable");
}
return ;
}

HDU 1043 Eight(八数码)的更多相关文章

  1. HDU 1043 Eight 八数码问题 A*算法(经典问题)

    HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...

  2. Hdu 1043 Eight (八数码问题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目描述: 3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动 ...

  3. hdu 1043 Eight (八数码问题)【BFS】+【康拓展开】

    <题目链接> 题目大意:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 解题分析:本题用BFS来寻找路径,为 ...

  4. HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法

    先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...

  5. 【双向广搜+逆序数优化】【HDU1043】【八数码】

    HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...

  6. hdu 1043 Eight 经典八数码问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...

  7. Eight POJ - 1077 HDU - 1043 八数码

    Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...

  8. HDU 1043 Eight (BFS&#183;八数码&#183;康托展开)

    题意  输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数  即这个排列在全部排列中的字典序  然后就是基础的BFS了 #include <bits/stdc++.h ...

  9. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

随机推荐

  1. java获取当前网站的IP地址

    package ip; import java.net.InetAddress; import java.net.UnknownHostException; /** * * @author * */ ...

  2. ERP实施顾问--理解客户的解决方案与实际需求

    在企业进行信息化时实施方的顾问都会来现场进行"需求调研",再根据"调研"的结果进行双方确认,确认后按此蓝本进行开发实施. 一切看上去都很美好,需求明确.开发顺利 ...

  3. HTML 5 拖放 drag dragend dragover ....

    拖放(Drag 和 drop)是 HTML5 标准的组成部分. // http://www.w3school.com.cn/html5/html_5_draganddrop.asp dataTrans ...

  4. DELPHI中完成端口(IOCP)的简单分析(2)

    DELPHI中完成端口(IOCP)的简单分析(2)   今天我写一下关于DELPHI编写完成端口(IOCP)的工作者线程中的东西.希望各位能提出批评意见.上次我写了关于常见IOCP的代码,对于IOCP ...

  5. SQL 查询嵌套使用

    .查询: 各年级中 分数最高的学习信息   示例表如下:   create table it_student( id int primary key auto_increment,  -- 主键id ...

  6. caffe编译报错 cudnn.hpp:127:41: error: too few arguments to function ‘cudnnStatus_t cudnnSetPooling2dDescriptor

    转载自: https://blog.csdn.net/u011070171/article/details/52292680 这是因为当前版本的caffe的cudnn实现与系统所安装的cudnn的版本 ...

  7. vue router相关用法

    router.push(location) 想要导航到不同的 URL,则使用 router.push 方法.这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之 ...

  8. MySQL服务安全加固

    数据库管理人员可以参考本文档进行 MySQL 数据库系统的安全配置加固,提高数据库的安全性,确保数据库服务稳定.安全.可靠地运行. 漏洞发现 您可以使用安骑士企业版自动检测您的服务器上是否存在 MyS ...

  9. UVA 11582 Colossal Fibonacci Numbers(数学)

    Colossal Fibonacci Numbers 想先说下最近的状态吧,已经考完试了,这个暑假也应该是最后刷题的暑假了,打完今年acm就应该会退了,但是还什么都不会呢? +_+ 所以这个暑假,一定 ...

  10. 前端学习历程--css①

    ---恢复内容开始--- 本文用自己的理解,总结网上或者自身经历的问题,加以汇总,方便查找: 一.浏览器默认样式 1.浏览器处理css&html a.css作用范围:盒子模式.浮动.定位.背景 ...