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来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...
随机推荐
- 原始的Ajax方法 (异步的 JavaScript 和 XML -- (Extensible Markup Language 可扩展标记语言))
<script language="javascript" type="text/javascript"> var request = false; ...
- ssh框架-Struts2(二)
上篇文章我们了解了怎么配置struts.xml文件,以及前端控制器配置怎么配置,,Action进阶,Result结果配置,Struts2中的Servlet的API的访问,以及怎么获得请求参数.今天我们 ...
- Spring Security 入门(1-8)Spring Security 的配置文件举例
- apigw鉴权分析(1-2)腾讯开放平台 - 鉴权分析
一.访问入口 http://wiki.open.qq.com/wiki/%E8%85%BE%E8%AE%AF%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0%E7%AC%AC% ...
- JS中全等和相等操作符的区别和比较规则
一.两者的区别 相等:先强制转换变量类型,再比较 全等:不转换类型,一旦类型不同,就是不全等. 二.相等和不相等的比较规则 1.操作符中有布尔值时: 比较前先将之转换为数值 false => 0 ...
- 赛码网算法: 上台阶 ( python3实现 、c实现)
上台阶 题目描述 有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法?注:规定从一级到一级有0种走法. 输入输入数据首先包含一个整数n(1<=n<=1 ...
- python request
python request a. 客户端向服务端发送多层字典的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 obj = ...
- Java:现有线程T1/T2/T3,如何确保T1执行完成之后执行T2,T3在T2执行完成之后执行。
要实现多个线程执行完成先后,就要知道如何实现线程之间的等待,java线程等待实现是join.java的jdk中join方法实现如下: public final synchronized void jo ...
- MongoDB的安装和使用指南
什么是MongoDB MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系 ...
- ZOJ-2913 Bus Pass---BFS进阶版
题目链接: https://vjudge.net/problem/ZOJ-2913 题目大意: 问哪个区域到公交路线上所有区域的最大距离最小 思路: 这里要求出到底是哪个区域到某些指定区域的最大距离最 ...