hdu3567 八数码(搜索)--预处理
题意:为你两个状态,求a到b 的最小路径,要求字典序最小。
思路:
最开始想的是目标状态是变化的,所以打表应该不行,然后直接上A*,但是TLE了- -(瞬间无语)
然后看了下别人的思路,预处理出9个状态(好机智),然后打表。
因为x所在的位置只有9中,我们可以根据x的位置打表,而且不同的串可以等效替代
例: 564178x23 7568x4123
--> 123456x78 5126x3478
而且题目保证一定会有解。 所以bfs+打表,至于双向bfs,写了发现一直cuo,后来发现在反向搜索时很难保证最小字典序,如果有两条路走到同一个节点,你就要比较它们长短,一样则比大小
问题:
①没考虑到a = b时的情况(果然很水)
②a = b时后面还有空行- -,也是醉的不行
③考虑不够全面,一开始就把打表这个排除了,
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
typedef long long ll;
using namespace std; const int maxn = 3700000;
int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
int vis[10][maxn]; struct node
{
int matrix[10];
int position;
int state;
}; int cantor(int s[])
{
int sum = 0;
for(int i = 0; i < 9; i ++)
{
int num = 0;
for(int j = i+1; j < 9; j++)
if(s[j] < s[i]) num++;
sum += (num*fac[9-i-1]);
}
return sum + 1;
} struct node2
{
int pre;
char ch;
} pre[10][maxn]; char dire[5]="dlru";
int dir[4] = {3,-1,1,-3};
node cur; void bfs(int t)
{
queue<node>q;
vis[t][cur.state] = 1;
int tnum = 1;
pre[t][1].pre = -1;
q.push(cur);
while(!q.empty())
{
cur = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
if(i==3&&cur.position<3)continue;
if(i==2&&cur.position%3==2)continue;
if(i==0&&cur.position>5)continue;
if(i==1&&cur.position%3==0)continue;
node tmp = cur;
tmp.position = cur.position + dir[i];
tmp.matrix[cur.position] = tmp.matrix[tmp.position];
tmp.matrix[tmp.position] = 0;
tmp.state = cantor(tmp.matrix);
if(!vis[t][tmp.state])
{
vis[t][tmp.state] = ++tnum;
pre[t][tnum].ch = dire[i];
pre[t][tnum].pre = vis[t][cur.state];
q.push(tmp);
}
}
}
return ;
}
int all;
void pri(int t,int k)
{
if(pre[t][k].pre == -1)
{
printf("%d\n",all);
return;
}
all++;
pri(t,pre[t][k].pre);
printf("%c",pre[t][k].ch);
} void get_(int k)
{
int tot = 0;
for(int i = 0; i < 9; i++)
{
if(i == k)
continue;
else
cur.matrix[i] = ++tot;
}
cur.matrix[k] = 0;
cur.position = k;
cur.state = cantor(cur.matrix);
} int num[10];
int main()
{
get_(0);
bfs(0);
get_(1);
bfs(1);
get_(2);
bfs(2);
get_(3);
bfs(3);
get_(4);
bfs(4);
get_(5);
bfs(5);
get_(6);
bfs(6);
get_(7);
bfs(7);
get_(8);
bfs(8); node from,to;
int cas = 1;
int n;
scanf("%d",&n);
char a[10];
char b[10];
while(n--)
{
scanf("%s",a);
scanf("%s",b);
printf("Case %d: ",cas++);
int posi;
for(int i = 0,j = 0; i < strlen(a); i++)
{
if(a[i] == 'x' || a[i] == 'X')
posi = i; else
num[a[i]-'0'] = j++;
} for(int i = 0; i < strlen(b); i++)
{
if(b[i] == 'x' || b[i] == 'X')
{
from.position = i;
from.matrix[i] = 0;
}
else
{
from.matrix[i] = num[b[i]-'0']+1;
}
}
from.state = cantor(from.matrix);
if(!strcmp(a,b))
{
printf("0\n");
printf("\n");
continue;
}
// for(int i = 0; i < 9; i++)
// printf("%d ",from.matrix[i]);
//
// printf("%d",from.state);
all = 0;
pri(posi,vis[posi][from.state]);
printf("\n");
}
return 0;
}
hdu3567 八数码(搜索)--预处理的更多相关文章
- HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)
题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...
- hdu3567 八数码2(康托展开+多次bfs+预处理)
Eight II Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 130000/65536 K (Java/Others)Total S ...
- [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)
快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...
- 八数码问题:C++广度搜索实现
毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限 ...
- HDU 1043 八数码(A*搜索)
在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...
- [luogu]P1379 八数码难题[广度优先搜索]
八数码难题 ——!x^n+y^n=z^n 我在此只说明此题的一种用BFS的方法,因为本人也是初学,勉勉强强写了一个单向的BFS,据说最快的是IDA*(然而蒟蒻我不会…) 各位如果想用IDA*的可以看看 ...
- codevs1225八数码难题(搜索·)
1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启 ...
- 【双向广搜+逆序数优化】【HDU1043】【八数码】
HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...
- 洛谷P1379八数码难题
题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...
随机推荐
- 理解Python迭代对象、迭代器、生成器
作者:zhijun liu链接:https://zhuanlan.zhihu.com/p/24376869来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本文源自RQ作 ...
- bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作
http://www.lydsy.com/JudgeOnline/problem.php?id=2333 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ...
- linux 下 nc 命令的使用
netcat被誉为网络安全界的'瑞士军刀',一个简单而有用的工具,透过使用TCP或UDP协议的网络连接去读写数据.它被设计成一个稳定的后门工具,能够直接由其它程序和脚本轻松驱动.同时,它也是一个功能强 ...
- 开发者的如何优雅的使用OSX
Mac对于IT开发者来说是最好的开发工具,没有之一. 但是对于大部分人来说,第一个接触的PC操作系统都是Windows系统,此文将带大家优雅的快速学习和使用Mac的OSX系统. 1. 从键盘说起 Ma ...
- django报错invalid literal for int() with base 10: ''
这种错误是因为模型类中某个字段的条件约束为int类型,但是给了一个字符串类型,所以报错,找到那个模型类的字段,并对应修改就好了.
- Windows Powershell脚本执行
在cmd下执行powershell进入shell模式: 变量定义:$i = 10 $a = ifconfig | findstr "192" Windows下的命令都可以执行如: ...
- app测试中遇到问题总结
工作总结: 1 这两天由于工作,需要进行抓包,使用了Charles,fidder,发现一个坑点: charles没有抓到返回值的时候,默认是不在列表显示请求信息的,能不能设置,我就不知道了,但是可以在 ...
- hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(1)安装jdk
一.文件准备 下载jdk-8u131-linux-x64.tar.gz 二.工具准备 2.1 Xshell 2.2 Xftp 三.操作步骤 3.1 解压文件: $ tar zxvf jdk-8u131 ...
- 新概念英语(1-51)A pleasant climate
新概念英语(1-51)A pleasant climate Does it ever snow in Greece? A:Where do you come from? B:I come from G ...
- python中导入模块的本质, 无法导入手写模块的解决办法
最近身边一些朋友发生在项目当中编写自己模块,导入的时候无法导入的问题. 下面我来分享一下关于python中导入模块的一些基本知识. 1 导入模块时寻找路径 在每一个运行的python程序当中,都维护了 ...