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 ...
随机推荐
- [置顶] 顿悟JAVA,自己实现Object的Clone的约束关系(上)
因protected 的理解,顿悟一些JAVA的原理,模拟了Object类的子类为什么在调用clone方法前实现Cloneable接口. 这里不解释 ,上代码先. 运行效果 文件结构 调用类 pack ...
- <php>Ajax基本格式
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...
- C# 使用Sqlite 如何返回统计行数
Visual 2010 with Sqlite 需要这样Query 数据: select count(*) from tblOrder where OrderStartTime >= '2013 ...
- 企业生产环境中linux系统分区的几种方案
方案1:针对网站集群架构中的某个节点服务器分区 该服务器上的数据有多份(其他节点也有)且数据不太重要,建议分区方案如下: /boot: 200MB swap: 物理内存的1.5倍,当内存大于或等于8G ...
- openwrt上网配置的一些理解
其实已经有很多帖子讲过openwrt路由器上网配置了,我这里主要是讲我自己的一块硬件路由使用openwrt后的一些上网配置.之所以要研究我自己的配置,是因为硬件,硬件不一样,配置也就不一样,但是总的原 ...
- DEV SIT UAT
DEV环境:DEV顾名思义就是develop,即代码开发的环境.SIT环境:System Integration Test系统集成测试,开发人员自己测试流程是否走通.UAT环境:User Accept ...
- (转)sql中 in 、not in 、exists、not exists 用法和差别
exists (sql 返回结果集为真) not exists (sql 不返回结果集为真) 如下: 表A ID NAME 1 A1 2 A2 3 A3 表B ID AI ...
- .NET技术
1.在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别.回答要点:说明详细的空间分配.(10分) 解:string str=null ...
- EMCA常用命令 【weber整理必出精品】
EMCA常用命令 创建一个EM资料库 emca -repos create 重建一个EM资料库 emca -repos recreate 删除一个EM资料库 emca -repos drop 配置数据 ...
- poj1915 BFS
D - 广搜 基础 Crawling in process... Crawling failed Time Limit:1000MS Memory Limit:30000KB 64bi ...