hdu3095-Eleven puzzle(双向搜索+哈希)

The tile in black means it’s empty
Each step you can move only one tile.
Here comes the problem.How many steps at least it required to done the game.
Input
Every case contains five lines to describe the initial status of the board. 0 means empty.
It’s confirmed that the board is legal.
Output
Sample Input
Sample Output
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<iostream>
- #include<sstream>
- #include<algorithm>
- #include<utility>
- #include<vector>
- #include<set>
- #include<map>
- #include<queue>
- #include<cmath>
- #include<iterator>
- #include<stack>
- using namespace std;
- const int INF=1e9+;
- const double eps=1e-;
- const int mod=;
- const int maxn=;
- int f[],r[]; //双向bfs的两个队列的队首队尾指针
- int dx[]={-,,,},dy[]={,-,,}; //方向数组
- bool in(int x,int y){ return x>=&&x<&&y>=&&y<; } //是否越界
- struct node
- {
- int px[],py[]; //保存2个空格的位置和整个数组
- int A[][];
- }nod[][maxn]; //0是前面搜,1是后面搜
- int B[][]={ //最终状态
- -,-,,-,-,
- -,,,,-,
- ,,,,,
- -,,,,-,
- -,-,,-,-
- };
- bool Same(int A[][]) //判断该状态是否与最终的状态相等
- {
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- if(A[i][j]!=B[i][j]) return false;
- return true;
- }
- int F[]; //保存2^i
- void GetF()
- {
- F[]=;
- for(int i=;i<;i++) F[i]=F[i-]*;
- }
- int Get(int A[][]) //得到哈希值
- {
- int ret=,k=;
- for(int i=;i<;i++)
- for(int j=;j<;j++) if(A[i][j]>) ret+=F[k++]*A[i][j]; //乘上一个权值
- return ret;
- }
- struct Hash
- {
- int v,next,nid,k; //是哈希值,next指向下一个节点,nid和k分别保存是下标和0或1
- }ha[mod+maxn];
- int hash_id;
- bool check(int a,int k1,int b,int k2) //判断是否完全相等
- {
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- if(nod[k1][a].A[i][j]!=nod[k2][b].A[i][j]) return false;
- return true;
- }
- int Insert_Hash(int v,int nid,int k) //插入
- {
- int a=v%mod;
- int p=ha[a].next;
- while(p!=-)
- {
- if(ha[p].v==v&&check(ha[p].nid,ha[p].k,nid,k)) return ha[p].k;//有相同的状态
- p=ha[p].next;
- }
- p=++hash_id; //没有则增加新节点,前插法
- ha[p].v=v; ha[p].nid=nid; ha[p].k=k;
- ha[p].next=ha[a].next; ha[a].next=p;
- return -; //-1代表插入了新节点
- }
- bool AddNode(node& t,int i,int j,int k)
- {
- int x=t.px[i],y=t.py[i];
- int nx=x+dx[j],ny=y+dy[j];
- if(!in(nx,ny)||t.A[nx][ny]<=) return false;
- node& tt=nod[k][r[k]];
- tt=t;
- swap(tt.A[x][y],tt.A[nx][ny]); //交换
- tt.px[i]=nx; tt.py[i]=ny;
- int a=Insert_Hash(Get(tt.A),r[k],k);
- if(a==-){ r[k]++; return false; } //队尾指加1
- else if(a==k) return false; //自己原来访问过的状态
- else return true; //相遇了,找到了解
- }
- void Print(node& t)
- {
- for(int i=;i<;i++)
- {
- for(int j=;j<;j++) printf("%d ",t.A[i][j]);
- puts("");
- }
- puts("=========");
- getchar();
- }
- bool bfs(int k)
- {
- int& be=f[k];
- int en=r[k];
- while(be<en)
- {
- node& t=nod[k][be++];
- //Print(t);
- for(int i=;i<;i++)
- for(int j=;j<;j++) if(AddNode(t,i,j,k)) return true;
- }
- return false;
- }
- int solve()
- {
- if(Same(nod[][].A)) return ;
- for(int i=;i<;i++)
- for(int j=;j<;j++) nod[][].A[i][j]=B[i][j]; //最终状态
- nod[][].px[]=; nod[][].py[]=;
- nod[][].px[]=; nod[][].py[]=;
- int step=;
- f[]=f[]=,r[]=r[]=;
- for(int i=;i<mod;i++) ha[i].next=-;
- hash_id=mod-;
- while(f[]<r[]||f[]<r[]) //双向搜
- {
- step++;
- if(bfs()) return step;
- step++;
- if(bfs()) return step;
- if(step>=) return -;
- }
- return -;
- }
- int main()
- {
- int T;
- GetF();
- scanf("%d",&T);
- while(T--)
- {
- int k=;
- for(int i=;i<;i++)
- for(int j=;j<;j++)//得到初始状态
- {
- if(B[i][j]==-) { nod[][].A[i][j]=-; continue; }
- scanf("%d",&nod[][].A[i][j]);
- if(nod[][].A[i][j]==)
- { nod[][].px[k]=i; nod[][].py[k++]=j; }
- }
- int ans=solve();
- if(ans==-) printf("No solution!\n");
- else printf("%d\n",ans);
- }
- return ;
- }
hdu3095-Eleven puzzle(双向搜索+哈希)的更多相关文章
- Eleven puzzle_hdu_3095(双向广搜).java
Eleven puzzle Time Limit: 20000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- Eight(bfs+全排列的哈希函数)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22207 Accepted: 9846 Special Judge ...
- poj1200Crazy Search (哈希)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Crazy Search Time Limit: 1000MS Memory ...
- POJ 1200:Crazy Search(哈希)
Crazy Search Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 32483 Accepted: 8947 Des ...
- POJ-3131-Cubic Eight-Puzzle(双向BFS+哈希)
Description Let's play a puzzle using eight cubes placed on a 3 × 3 board leaving one empty square. ...
- Crazy Search POJ - 1200 (字符串哈希hash)
Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could ...
- [PHP内核探索]PHP中的哈希表
在PHP内核中,其中一个很重要的数据结构就是HashTable.我们常用的数组,在内核中就是用HashTable来实现.那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据 ...
- java单向加密算法小结(2)--MD5哈希算法
上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...
- Java 哈希表运用-LeetCode 1 Two Sum
Given an array of integers, find two numbers such that they add up to a specific target number. The ...
随机推荐
- hdu4641-K-string(后缀自动机)
Problem Description Given a string S. K-string is the sub-string of S and it appear in the S at leas ...
- 使用kthread内核线程的内核模块
这里使用了msleep(50); printk 开启其实挺大的,当我使用msleep(10);机器直接卡死了: 另外ISERR不能判断结构体的,只能判断 空指针 #cat hello.c #inclu ...
- Spring的工作原理核心组件和应用
Spring框架 Spring 是管理多个java类的容器框架,注意是类不管理接口. Spring 的主要功能 Ioc 反转控制和 DI 依赖注入. 注入的方式可以是构造函数赋值也可以是 set方法赋 ...
- Head First Html 与 Css 截图
1.认识HTML web语言 2.深入了解超文本 HTML中的"HT" 3. 构建模块 web页面建设 4. 连接起来 5. 认识媒体,为页面添加图像 6. 严肃的HTML标准及其 ...
- 字典树-百度之星-Xor Sum
Xor Sum Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包括了N个正整数,随后 Prometheu ...
- Laravel 4 Blade模板引擎
http://my.oschina.net/5say/blog/201290 模板输出 基本输出 1 <!-- app/views/example.blade.php --> 2 < ...
- web工程调用hadoop集群1.2
本实例代码在lz的资源中有上传,有需要的可以参考(下载后的文件解压后有两个,一个直接导入myeclipse工程,另外的jar放在hadoop的lib下面,只需修改Utils中的ip即可运行该程序): ...
- LoadRuner性能测试之内存分析方法及步骤(Windows)
1.首先观察Available Mbytes(可用内存),至少要>=1/2的内存空间 2.然后观察Pages/sec值是不是很大 3.再观察Page Faules/sec是不是很大,其值表示 ...
- java web实现读取指定盘符下的图像(二)
之前写了一篇文章是关于如何读取指定盘符下的图片,虽然功能可以实现,但是使用的是I/O流的方式,效率不高.现在发现还有一个更好的办法,使用也更加的方便. 我们知道,当我们的图片是放在tomcat下web ...
- vim搜索后跳到下(上)一个
搜索高亮后, 跳到下一个:小写n 上一个:大写N