HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
http://acm.hdu.edu.cn/showproblem.php?pid=3567
相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过,而且也不好控制字典序
换个角度想,虽然起始状态有很多,但是到底哪一位是1,哪一位是2不是最重要的,最重要的是和目标状态对应,所以可以把起始状态重新编码为"12345678"这种形式(先不考虑X),然后目标状态也对应过去,当考虑X的时候,我们可以认为起始状态只有9种,分别是'X'在各个位置的情况
利用bfs可以得到每种起始状态到对应的能够达到的所有目标状态的最短最小字典序转移方法,如果对每个状态都记录一个字符串肯定会MLE,所以只需要记录上一个状态到这一个状态转移所需要的操作即可
最后,对于每个目标状态,逆向推出状态转移序列,然后逆着输出即可
ps:一次处理3.6e6个状态,如果不用queue或者循环数组会MLE,如果不用g++提交而用c++提交会TLE
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cctype>
using namespace std;
const int base[9]={1,1,2,6,24,120,720,5040,40320};
const int dx[4]={1,0,0,-1};/转移方向,遵从字典序最小
const int dy[4]={0,-1,1,0};
const int maxh=362880;//每种开始状态所对应状态数
int des;//用于存储目标状态hash值,判断是否不需要转移
struct pnt{
int maz[3][3];
int ind;//标记起始状态的编号
int x,y;
int hashCode;
pnt(){
x=y=hashCode=-1;
}
pnt(char * str){
for(int i=0;i<9;i++){
if(str[i]=='X'){
maz[i/3][i%3]=9;
x=i/3;
y=i%3;
ind=i;
}
else maz[i/3][i%3]=str[i]-'0';
}
}
int gethashcode(){
int ans=0;
for(int i=0;i<9;i++){
int cnt=0;
for(int j=0;j<i;j++){
if(maz[j/3][j%3]>maz[i/3][i%3]){
cnt++;
}
}
ans+=base[i]*cnt;
}
return hashCode=ind*maxh+ans;
}
};
bool in(int tx,int ty){
return tx>=0&&tx<3&&ty>=0&&ty<3;
} int vis[maxh*10+1];//用于存储某状态是否已被遍历,并存储由何种操作得到该状态
int pre[maxh*10+1];//用于存储某状态由何种状态转移得到
queue<pnt> que;
char ans[maxh*10+1];//存储答案的逆序
char buff[300];//存储输入
pnt s,e;
int ind[10],indlen;//用于重新编码
bool input(){
if(scanf("%s",buff)!=1)return false;
indlen=0;//重新编码
for(int i=0;i<9;i++){
if(buff[i]>='0'&&buff[i]<='9'){
s.maz[i/3][i%3]=++indlen;
ind[buff[i]-'0']=indlen;
}
else{
s.maz[i/3][i%3]=9;
s.x=i/3;
s.y=i%3;
s.ind=i;
}
}
if(scanf("%s",buff)!=1)return false;
for(int i=0;i<9;i++){
if(buff[i]>='0'&&buff[i]<='9'){
e.maz[i/3][i%3]=ind[buff[i]-'0'];
}
else{
e.maz[i/3][i%3]=9;
e.x=i/3;
e.y=i%3;
}
}
e.ind=s.ind;//起始状态相同
des=e.gethashcode();
return true;
}
void bfs(){
while(!que.empty()){
pnt tp=que.front();que.pop();
int x=tp.x,y=tp.y;
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(in(tx,ty)){
pnt nw=tp;
swap(nw.maz[tx][ty],nw.maz[x][y]);
nw.x=tx,nw.y=ty;
if(vis[nw.gethashcode()]==-1){
vis[nw.hashCode]=i;
pre[nw.hashCode]=tp.gethashcode();
que.push(nw);
}
}
}
}
}
void init(){
memset(vis,-1,sizeof(vis));
memset(pre,-1,sizeof(pre));
pnt s1=pnt("12345678X");//9种起始状态加入序列
vis[s1.gethashcode()]=-2;
que.push(s1);
pnt s2=pnt("1234567X8");
vis[s2.gethashcode()]=-2;
que.push(s2);
pnt s3=pnt("123456X78");
vis[s3.gethashcode()]=-2;
que.push(s3);
pnt s4=pnt("12345X678");
vis[s4.gethashcode()]=-2;
que.push(s4);
pnt s5=pnt("1234X5678");
vis[s5.gethashcode()]=-2;
que.push(s5);
pnt s6=pnt("123X45678");
vis[s6.gethashcode()]=-2;
que.push(s6);
pnt s7=pnt("12X345678");
vis[s7.gethashcode()]=-2;
que.push(s7);
pnt s8=pnt("1X2345678");
vis[s8.gethashcode()]=-2;
que.push(s8);
pnt s9=pnt("X12345678");
vis[s9.gethashcode()]=-2;
que.push(s9);
bfs();
}
int heap[maxh],sz;
int getans(pnt e){//逆序遍历
sz=0;
int last=e.gethashcode();
while(pre[last]>=0){
heap[sz++]=vis[last];
last=pre[last];
}
return sz;
}
void print(){
for(int i=sz-1;i>=0;i--){
switch(heap[i]){
case 0:
putchar('d');break;
case 1:
putchar('l');break;
case 2:
putchar('r');break;
case 3:
putchar('u');break;
}
}
putchar('\n');
}
int main(){
int T;
scanf("%d",&T);
init();
for(int ti=1;ti<=T;ti++){
input();
s.hashCode=s.gethashcode();
if(s.hashCode==des){
printf("Case %d: 0\n",ti);
puts("");
continue;
}
vis[s.hashCode]=-2;
int step=getans(e);
printf("Case %d: %d\n",ti,step);
print();
}
return 0;
}
HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3的更多相关文章
- 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 3567 Eight II(八数码 II)
HDU 3567 Eight II(八数码 II) /65536 K (Java/Others) Problem Description - 题目描述 Eight-puzzle, which is ...
- HDU 1043 Eight(反向BFS+打表+康托展开)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...
- [HDOJ1043]Eight(康托展开 BFS 打表)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 八数码问题,因为固定了位置所以以目标位置开始搜索,把所有情况(相当于一个排列)都记录下来,用康托 ...
- hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...
- HDU1430 BFS + 打表 + 康托展开
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 , 一道比较好的题. 这道题要用到很多知识,康托展开.BFS.打表的预处理还要用到一一映射,做完 ...
- HDU 1430 魔板(康托展开+BFS+预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
随机推荐
- (六)ARM状态寄存器-PSR
ARM程序状态寄存器Program State Register 在ARM模式中, 有16个数据寄存器和1或2个状态寄存器是可以随时访问的.在特权模式 (privileged mode) 下, 对应的 ...
- ios 开发之 Xcode6 No valid signing identities (i.e. certificate and private key pair) matching...
之前的项目用证书真机测试过,我想再无证书Build,出现下面的报错提示! 下面的team我无法改成None!一点击None选的还是Unhonw name(JPGE28K3W9)这个是报错的关键 最后由 ...
- 开启所有PHP错误!无论在任何时候
开发的时候,会屏蔽所有错误,但是有时候排查太蛋疼, 下面代码粘贴到控制器头部,开所有错误! 不可阻挡 ini_set('display_errors','1'); restore_error_ha ...
- hiho_1138_island_travel
题目 二维平面上有n个点,每个点的横纵坐标均为非负整数.两个点之间的距离记为 min(abs(x1 - x2), abs(y1 - y2)),求从点1到达点n的最短路径长度. 比较容易想到使用最短路径 ...
- 如何设置session过期时间为30分钟
今天在我的微博(Laruence)上发出一个问题: 我在面试的时候, 经常会问一个问题: “如何设置一个30分钟过期的Session?”, 大家不要觉得看似简单, 这里面包含的知识挺多, 特别适合考察 ...
- 【MRPT】【icp-slam-live】Vs2013+ cmake3.6.1 + mrpt1.4.0+opencv2.9.4+wxWidget3.0.2环境配置
Win10下Vs2013 + cmake3.6.1 + mrpt1.4.0+opencv2.9.4+wxWidget3.1.0环境配置 所接触过的最令我崩溃的环境配置.之前没有考虑到vs2013 20 ...
- [ 转]Android快速开发–使用ORMLite操作数据库
OrmLite是一个数据库操作辅助的开源框架,主要面向Java语言.在Android面向数据库开发中,是一个比较流行的开源框架,方便操作而且功能强大,今天来学习一下,最近的项目中也有所涉及,写个博客来 ...
- Machine Learning for hackers读书笔记(三)分类:垃圾邮件过滤
#定义函数,打开每一个文件,找到空行,将空行后的文本返回为一个字符串向量,该向量只有一个元素,就是空行之后的所有文本拼接之后的字符串 #很多邮件都包含了非ASCII字符,因此设为latin1就可以读取 ...
- [Hadoop 周边] Hadoop和大数据:60款顶级大数据开源工具(2015-10-27)【转】
说到处理大数据的工具,普通的开源解决方案(尤其是Apache Hadoop)堪称中流砥柱.弗雷斯特调研公司的分析师Mike Gualtieri最近预测,在接下来几年,“100%的大公司”会采用Hado ...
- Scrum 项目5.0
1.团队成员完成自己认领的任务. 2.燃尽图:理解.设计并画出本次Sprint的燃尽图的理想线.参考图6. 3.每日立会更新任务板上任务完成情况.燃尽图的实际线,分析项目进度是否在正轨. 每天的 ...