因为是计算还原成一种局面的最短步骤,应该想到从最终局面开始做bfs,把所有能到达的情况遍历一遍,把值存下来。

bfs过程中,访问过的局面的记录是此题的关键,9*9的方格在计算过程中直接存储非常占内存。而这个显然是12345678x的不同排列,考虑康拓展开来记录,每个局面hash成一个整数。步骤我先算了一下,最多有31步,我用4进制位hash成了两个整数来保存

#include <iostream>
#include <iomanip>
#include <set>
#include <cmath>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#define LL long long
using namespace std;
class cantor
{
public:
#define siz 9
char c[siz]={'','','','','','','','','x'};
LL w[siz];
bool vis[siz];
cantor()
{
w[]=;
for(int i=;i<siz;i++)
w[i]=w[i-]*i;
}
void init()
{
for(int i=;i<siz;i++)
vis[i]=false;
}
LL makeCanto(string s)
{
init();
LL rec=;
for(int i=;i<siz;i++)
{
int d=;
for(int j=;j<siz;j++)
{
if(vis[j])
continue;
if(c[j]!=s[i])d++;
else
{
vis[j]=true;
break;
}
}
rec+=w[siz-i-]*d;
}
return rec;
}
string recover(LL val)
{
init();
string s="";
for(int i=siz-;i>=;i--)
{
LL te=val/w[i];
val-=e*w[i];
for(int j=,cnt=-;j<siz;j++)
{
if(vis[j])continue;
else cnt++;
if(cnt==te&&!vis[j])
{
s+=c[j];
vis[j]=true;
break;
}
}
}
return s;
}
};
LL n,m;
char mp[][];
set<LL> s;
string ss="";
const string las="12345678x";
bool f;
int dir[][]={-,,,,,,,-};
char dfuck[]={'d','u','l','r'};
struct node
{
LL s;
int c;
int x,y;
LL a,b;
node(LL ss,int aa,int X,int Y,LL A,LL B){s=ss;c=aa;x=X;y=Y;a=A;b=B;}
};
struct ax
{
LL a,b,c;
ax(LL A,LL B,LL C){a=A;b=B;c=C;}
ax(){}
};
map<LL,ax> ans;
LL bit[];
int main()
{
cin.sync_with_stdio(false);
cantor fx;
bit[]=;
for(int i=;i<;i++)
bit[i]=bit[i-]*;
queue<node> q;
node ini=node(fx.makeCanto(las),,,,,);
q.push(ini);
s.clear();
ans.clear();
int mx=;
s.insert(fx.makeCanto(las));
while(!q.empty())
{
node now=q.front();
ans[now.s]=ax(now.a,now.b,now.c);
q.pop();
mx=max(now.c,mx);
for(int i=;i<;i++)
{
int yy=now.y+dir[i][];
int xx=now.x+dir[i][];
if(xx<||yy<||xx>=||yy>=)continue;
string nx=fx.recover(now.s);
swap(nx[now.y*+now.x],nx[yy*+xx]);
LL nxv=fx.makeCanto(nx);
if(s.find(nxv)!=s.end())continue;
s.insert(nxv);
LL na=now.a,nb=now.b;
if(now.c<)
{
na+=i*bit[now.c];
}
else
{
nb+=i*bit[now.c-];
}
q.push(node(nxv,now.c+,xx,yy,na,nb));
}
}
while(cin>>mp[][]>>mp[][]>>mp[][]>>mp[][]>>mp[][]>>mp[][]>>mp[][]>>mp[][]>>mp[][])
{
int x,y;
f=false;
s.clear();
ss="";
for(int i=;i<;i++)
for(int j=;j<;j++)
{
ss+=mp[i][j];
if(mp[i][j]=='x')
y=i,x=j;
}
string o="";
if(ss=="12345678x")
{
cout<<"lr"<<endl;
continue;
}
if(ans.find(fx.makeCanto(ss))==ans.end())
{
cout<<"unsolvable"<<endl;
continue;
}
ax fuck=ans[fx.makeCanto(ss)];
for(int i=;i<fuck.c;i++)
{
if(i<)
{
o+=dfuck[fuck.a%];
fuck.a/=;
}
else
{
o+=dfuck[fuck.b%];
fuck.b/=;
}
}
reverse(o.begin(),o.end());
cout<<o<<endl;
}
}

hdu-1043 bfs+康拓展开hash的更多相关文章

  1. HDU 4531 bfs/康拓展开

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4531 吉哥系列故事——乾坤大挪移 Time Limit: 2000/1000 MS (Java/Othe ...

  2. Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

  3. hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 http://poj.org/problem?id=1077 Eight Time Limit: 1000 ...

  4. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  5. 【HDOJ3567】【预处理bfs+映射+康拓展开hash】

    http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others)    Me ...

  6. bnuoj 1071 拼图++(BFS+康拓展开)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071 [题意]:经过四个点的顺逆时针旋转,得到最终拼图 [题解]:康拓展开+BFS,注意先预处理,得 ...

  7. 九宫重拍(bfs + 康拓展开)

    问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...

  8. 8数码,欺我太甚!<bfs+康拓展开>

    不多述,直接上代码,至于康拓展开,以前的文章里有 #include<iostream> #include<cstdio> #include<queue> using ...

  9. hdu 1430(BFS+康托展开+映射+输出路径)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

随机推荐

  1. 浅谈Java中的关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. ...

  2. python进阶之 网络编程

    1.tcp和udp协议的区别 TCP协议 面向连接\可靠\慢\对传递的数据的长短没有要求 两台机器之间要想传递信息必须先建立连接 之后在有了连接的基础上,进行信息的传递 可靠 : 数据不会丢失 不会重 ...

  3. Linux命令之rpm安装命令

    在 Linux 操作系统下,几乎所有的软件均通过RPM 进行安装.卸载及管理等操作.RPM 的全称为Redhat Package Manager ,是由Redhat 公司提出的,用于管理Linux 下 ...

  4. vmvare安装vmtools菜单灰色

    光驱和各种驱动器改为自动检测 将vmvaretools.gz文件解压 tar xvf vm...gz 然后进程解压目录运行 sudo ./vmware-install.pl 然后重启 reboot 这 ...

  5. IP地址和子网划分学习笔记之《IP地址详解》

    2018-05-03 18:47:37   在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. ...

  6. 星型数据仓库olap工具kylin介绍和简单使用示例

    本文转载自:https://www.cnblogs.com/hsydj/p/4515057.html 星型数据仓库olap工具kylin介绍 星型数据仓库olap工具kylin介绍 数据仓库是目前企业 ...

  7. javascript Template tmpl

    前两天写前端遇到很多table 和 表单需要拼接的问题 , 一堆的字符串 , 页面显得冗长,又不好维护.于是有了下文. 话不多说,上代码: 首先引用一个js文件: <script src=&qu ...

  8. 51Nod 1174 区间中最大的数

    给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少.   例如: 1 7 6 3 1.i = 1, j = 3,对应的数为7 6 3,最大的数为7. ...

  9. IDEA循环依赖报错解决方案

    step1.查找循环依赖 step2.在IDEA菜单栏中打开Analyze->Analyze Module Dependencies...看到有的模块被红色的标出来了,此时右边显示了循环依赖,那 ...

  10. 如何将数据库中的数据导入到Solr中

    要使用solr实现网站中商品搜索,需要将mysql数据库中数据在solr中创建索引. 1.需要在solr的schema.xml文件定义要存储的商品Field. 商品表中的字段为: 配置内容是: < ...