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
 #include<stdio.h>
#include<string.h>
#include<algorithm>
#include<ctype.h>
typedef long long ll ;
int map[][] ;
char mp[] ;
int l , r , l1 , r1 ;
int flag ;
int anti ;
int move[][] = {{,} , {-,} , {,} , {,-}} ;
const int mod = ;
struct node
{
int x , y , nxt ;
int map[][] ;
} b[mod];
struct hash
{
ll w , id ;
int nxt ;
}e[mod * ];
int H[mod * ] , E ; void insert (ll x , int id)
{
int y = x % mod ;
if (y < ) y += mod ;
e[++ E].w = x ;
e[E].id = id ;
e[E].nxt = H[y] ;
H[y] = E ;
} int find (ll x)
{
int y = x % mod ;
if (y < ) y += mod ;
for (int i = H[y] ; ~ i ; i = e[i].nxt ) {
if (e[i].w == x)
return e[i].id ;
}
return - ;
} void table ()
{
node ans , tmp ;
E = - ; memset (H , - , sizeof (H) ) ;
l1 = , r1= ;
b[l1].x = , b[l1].y = , b[l1].nxt = - ;
ll sum = ;
for (int i = ; i < ; i ++) for (int j = ; j < ; j ++) b[l1].map[i][j] = i * + j + ;
insert ( , ) ;
while (l1 != r1) {
ans = b[l1] ;
for (int i = ; i < ; i ++) {
tmp.x = ans.x + move[i][] ; tmp.y = ans.y + move[i][] ;
if (tmp.x < || tmp.y < || tmp.x >= || tmp.y >= ) continue ;
for (int i = ; i < ; i ++) for (int j = ; j < ; j ++) tmp.map[i][j] = ans.map[i][j] ;
std::swap (tmp.map[ans.x][ans.y] , tmp.map[tmp.x][tmp.y]) ;
sum = ;
for (int i = ; i < ; i ++) for (int j = ; j < ; j ++) sum = sum * + tmp.map[i][j] ;
if (find (sum) != - ) continue ;
insert (sum , r1 ) ;
tmp.nxt = l1 ;
b[r1 ++] = tmp ;
}
l1 ++ ;
}
} void solve (int u)
{
if (u == -) return ;
int t = b[u].nxt ;
if (t != -) {
int x = b[t].x - b[u].x , y = b[t].y - b[u].y ;
if (x == ) printf ("d") ;
else if (x == -) printf ("u") ;
else if (y == ) printf ("r") ;
else if (y == - ) printf ("l") ;
}
solve (t) ;
} int main ()
{
freopen ("a.txt" , "r" , stdin ) ;
table () ;
while (gets (mp) != NULL) {
int tot = ;
for (int i = ; mp[i] != '\0' ; i ++) {
if (mp[i] != ' ') {
if (isdigit (mp[i])) {
map[tot / ][tot % ] = mp[i] - '' ;
}
else map[tot / ][tot % ] = ;
tot ++ ;
}
}
ll sum = ;
for (int i = ; i < ; i ++) for (int j = ; j < ; j ++) sum = sum * + map[i][j] ;
anti = find (sum) ;
if (anti != -) solve (anti) ;
else printf ("unsolvable") ;
puts ("") ;
}
return ;
}

打表思路很简单,也是为了对抗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了.

hdu.1043.Eight (打表 || 双广 + 奇偶逆序)的更多相关文章

  1. Eight hdu 1043 八数码问题 双搜

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  2. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  3. HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)

    Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  4. hdu 1401(单广各种卡的搜索题||双广秒速)

    Solitaire Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  5. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  6. HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

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

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

  8. HDU 1043 八数码(八境界)

    看了这篇博客的讲解,挺不错的.http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 判断无解的情况(写完七种境界才发现有直接判 ...

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

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

随机推荐

  1. List多对多的查询应用

    /** * @param param * @author mercy 查询主副产品(主副产品是多对多的关系) * @return */ public String queryProductSpecAt ...

  2. UVa 437 The Tower of Babylon(经典动态规划)

    传送门 Description Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many details ...

  3. WPF资源字典

    如果相同的资源可用于不同的应用程序,把资源放在一个资源字典中就比较有效. 新建一个资源字典文件Dictionary1.xaml <ResourceDictionary xmlns="h ...

  4. HDU1698Just a Hook(线段树 + 区间修改 + 求和)

    题目链接 分析:1-N区间内初始都是1,然后q个询问,每个询问修改区间[a,b]的值为2或3或者1,统计最后整个区间的和 本来想刷刷手速,结果还是写了一个小时,第一个超时,因为输出的时候去每个区间查找 ...

  5. 深入JVM-垃圾收集器常用的GC参数

    1.与串行回收器相关的参数 -XX:+UseSerialGC:在新生代和老年代使用串行收集器 -XX:SurvivorRatio:设置eden区大小和survivor区大小的比例 -XX:Preten ...

  6. css中 Span 元素的 width 属性无效果原因及多种解决方案

    先运行下程序看下: <span style='width:300px;'>123</span> 输出:123 可以看到 span会自动根据包含的内容来变化宽度 这是因为:对于内 ...

  7. WinForm------GridControl中通过判断单元格文字显示不同字体颜色或背景色

  8. 10月16日上午MySQL数据库基础操作(创建、删除)

    以前用的是鼠标在界面上手动创建,这样创建会比较麻烦,而且还会经常出问题.在其它电脑上要用的话还需要重复操作.所以要使用程序代码操作,能通过代码的就不用手动操作. 在数据库界面选择要用的数据库,双击打开 ...

  9. CodeForces 716A Crazy Computer

    题目链接:http://codeforces.com/problemset/problem/716/A 题目大意: 输入 n c, 第二行 n 个整数,c表示时间间隔 秒. 每个整数代表是第几秒.如果 ...

  10. 移动端a标签点击图片有阴影处理

    移动端我们在点击页面中的一些图片的时候会出现阴影.处理方法只要给a标签加上 a { -webkit-tap-highlight-color: transparent; -webkit-touch-ca ...