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
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.
1 2 3 x 4 6 7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
#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 (打表 || 双广 + 奇偶逆序)的更多相关文章
- Eight hdu 1043 八数码问题 双搜
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...
- HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- hdu 1401(单广各种卡的搜索题||双广秒速)
Solitaire Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30176 Accepted: 13119 Special ...
- HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30176 Accepted: 13119 Special ...
- HDU 1043 Eight 八数码问题 A*算法(经典问题)
HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...
- HDU 1043 八数码(八境界)
看了这篇博客的讲解,挺不错的.http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 判断无解的情况(写完七种境界才发现有直接判 ...
- Eight POJ - 1077 HDU - 1043 八数码
Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...
随机推荐
- 为什么要用Markdown写东西
为什么要用Markdown 不用费心去调格式了,比方说题目加粗什么的,删除线什么的,代码也只要四个空格就好了~ 学起来很简单,几乎没什么学习成本,而收益却很大 这几乎快让我我想从cnblog转到简书了 ...
- VC++ 比较两个字符串是否相等,字母大小写相关。
1.strcmp 这是用于ANSI标准字符串的函数(如string和char *),此函数接受两个字符串缓冲区做为参数,如果两个字符串是相同的则返回零.否则若第一个传入的字符串的值大于第二个字符串返回 ...
- linux basis --- common commands
switch to root : sudo su switch to users : su god(user name) set root password : sudo passwd root ch ...
- MySQL中的外键是什么、有什么作用
本文参加博文大赛,如果您满意的话麻烦点击这里给我投票原,查看原文点击这里.最近自学数据库MySQL,然后有个疑问,一直不得其解,查询了相关资料,最后还是没有解决. 我的疑问是 "使用外键约束 ...
- Myeclipse如何设置字体大小
由于Myeclipse一般是英文版的,这就给英语不太好的人带来了一定的麻烦,有时连设置个字体都无法顺利进行!!! 工具/原料 Myeclipse 方法/步骤 双击启动Myeclipse 点击& ...
- python学习笔记-(五)字符串&字典
1.字符串操作 >>> name = ("my name is cc")#首字母大写 >>> print(name.capitalize()) ...
- linq lamda
var query6 = CustomerList.SelectMany(c => c.Orders);var query6= from c in CustomerList ...
- js 处理日期 看着比较全,备用
http://www.cnblogs.com/endora/archive/2012/12/06/endorahe.html js 处理日期 看着比较全,备用
- 自然语言19.1_Lemmatizing with NLTK(单词变体还原)
QQ:231469242 欢迎喜欢nltk朋友交流 https://www.pythonprogramming.net/lemmatizing-nltk-tutorial/?completed=/na ...
- 改造rm命令为mv
:刚在群里面看到小伙伴误操作把服务器上重要的文件给删掉了,于是google了下,找到一篇文章把rm命令改造成mv命令,源博客如下:http://blog.csdn.net/dataspark/arti ...