题意:为你两个状态,求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 八数码(搜索)--预处理的更多相关文章

  1. HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)

    题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...

  2. hdu3567 八数码2(康托展开+多次bfs+预处理)

    Eight II Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 130000/65536 K (Java/Others)Total S ...

  3. [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)

    快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...

  4. 八数码问题:C++广度搜索实现

    毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限 ...

  5. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

  6. [luogu]P1379 八数码难题[广度优先搜索]

    八数码难题 ——!x^n+y^n=z^n 我在此只说明此题的一种用BFS的方法,因为本人也是初学,勉勉强强写了一个单向的BFS,据说最快的是IDA*(然而蒟蒻我不会…) 各位如果想用IDA*的可以看看 ...

  7. codevs1225八数码难题(搜索·)

    1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description Yours和zero在研究A*启 ...

  8. 【双向广搜+逆序数优化】【HDU1043】【八数码】

    HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...

  9. 洛谷P1379八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...

随机推荐

  1. 【iOS】Swift ?和 !(详解)

    Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值, 也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化 .如果在使用变量之前不进行初始化就会报错: [ ...

  2. python之路--day13---函数--三元表达式,递归,匿名函数,内置函数-----练习

    1.文件内容如下,标题为:姓名,性别,年纪,薪资 egon male 18 3000 alex male 38 30000 wupeiqi female 28 20000 yuanhao female ...

  3. 关于 Ubuntu Linux 16.04中文版的 root 权限及桌面登录问题

    新接触 Ubuntu 的朋友大多会因为安装中没有提示设置 root 密码而不太清楚是什么原因. 起初 Ubuntu 团队希望安装尽可能的简单. 不使用 root , 在安装期间的两个用户交互步骤可以省 ...

  4. Python爬虫之urllib模块1

    Python爬虫之urllib模块1 本文来自网友投稿.作者PG,一个待毕业待就业二流大学生.玄魂工作室未对该文章内容做任何改变. 因为本人一直对推理悬疑比较感兴趣,所以这次爬取的网站也是平时看一些悬 ...

  5. 1.phpStrom连接远程代码

    1.选择一个新的文件 2.选择自己需要的传输方式 3.添加项目名+路径 4.填写连接基本信息 5.配置成功,下载完毕后,设计本地与远程代码同步修改 自此本地修改代码,同时修改远程服务器代码就设置完毕~ ...

  6. 新概念英语(1-103)The French Test

    Lesson 103 The French test 法语考试 Listen to the tape then answer this question. How long did the exam ...

  7. ELK学习总结(1-2)安装ElasticSearch

    1.下载安装      Centos6.4      jdk1.8.20以上 elasticsearch::https://www.elastic.co/downloads/elasticsearch ...

  8. 前端之JavaScript内容

    一.JavaScript概述 1.JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnv软件中),后将其改名ScriptEas ...

  9. python 开发之路 - 入门

    一. python 介绍 Python是著名的"龟叔"Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言.1991年 发布Python ...

  10. 菜鸟容易中的招__setattr__

    class Counter: def __init__(self): self.counter = 0 # 这里会触发 __setattr__ 调用 def __setattr__(self, nam ...