hdu-1043 bfs+康拓展开hash
因为是计算还原成一种局面的最短步骤,应该想到从最终局面开始做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的更多相关文章
- HDU 4531 bfs/康拓展开
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4531 吉哥系列故事——乾坤大挪移 Time Limit: 2000/1000 MS (Java/Othe ...
- 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 ...
- 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 ...
- 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]*( ...
- 【HDOJ3567】【预处理bfs+映射+康拓展开hash】
http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others) Me ...
- bnuoj 1071 拼图++(BFS+康拓展开)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071 [题意]:经过四个点的顺逆时针旋转,得到最终拼图 [题解]:康拓展开+BFS,注意先预处理,得 ...
- 九宫重拍(bfs + 康拓展开)
问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...
- 8数码,欺我太甚!<bfs+康拓展开>
不多述,直接上代码,至于康拓展开,以前的文章里有 #include<iostream> #include<cstdio> #include<queue> using ...
- hdu 1430(BFS+康托展开+映射+输出路径)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
随机推荐
- Spring Boot事务管理(中)
在上一篇 Spring Boot事务管理(上)的基础上介绍Spring Boot事务属性和事务回滚规则 . 4 Spring Boot事务属性 什么是事务属性呢?事务属性可以理解成事务的一些基本配置, ...
- python练习题-day11
1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件), 要求:登录成功一次,后续的函数都无需再输入用户名和密码 flag=False def wrapper(fun): def inn ...
- SpringBoot-@RequestParam
Request参数 在访问各种各样网站时,经常会发现网站的URL的最后一部分形如:?xxxx=yyyy&zzzz=wwww.这就是HTTP协议中的Request参数,它有什么用呢?先来看一个例 ...
- vs添加github代码库
1.安装git for windows 2.在vs中工具->扩展和更新,安装github extension 3.在项目中右键,添加源码到git,之后配置git,然后选择同步或者commit即可
- [js]js设计模式-单例模式
单例模式 不同模块之间需要同时开发, // 单例模式: 把描述同一个事物的属性和方法放在同一个内存空间下. // 优点: 分组,防止冲突 // p1 p2也叫做命名空间(模块开发) var p1 = ...
- shmdt() 与 shmctl() 的区别?
操作共享内存,我们用到了下面的函数 ============================================== #include <sys/types.h> #inclu ...
- 微信小程序 条件渲染 wx:if
1.在框架中,我们用wx:if="{{condition}}"来判断是否需要渲染该代码块 <view wx:if="{{condition}}"> ...
- Go 初体验 - 令人惊叹的语法 - defer.2 - 如何提前执行?
上一文中讲到 defer 会在宿主函数 return 之前调用,那么我们就是想在宿主函数执行到中间调用,怎么办呢? 1. 改变宿主函数逻辑,分成多个函数,需要的那个函数里 defer . 2. 使用匿 ...
- 3D印表機 零件採購資訊
3D印表機 零件採購資訊 採購資訊僅供參考,零件的品質由店家擔保! 壓克力 螺絲螺帽牙條 高來螺絲 滑套.軸承 五連軸承 掏寶-廣發軸承 光軸 掏寶-廣發軸承 彈簧 雅銅彈簧 鐵氟龍製品 馬達 電源供 ...
- mysql 事务锁超时时间 innodb_lock_wait_timeout
mysql 事务锁超时时间 innodb_lock_wait_timeout: # 查询全局等待事务锁超时时间 SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait ...