https://cn.vjudge.net/problem/HDU-3567

#include <stdio.h>
#include <math.h>
#include <queue>
#include <stack>
#include <string.h>
using namespace std;

struct Node
{
int s[9];
int loc;//存放0的位置
int state;//存放康托展开后的值
char d;
int fa;
}n[370000];
int len;
int dx[] = {1,0,0,-1};
int dy[] = {0,-1,1,0};
//按照字典序最小来搜索
char dir[] = "dlru";

int vis[9][370000];
long long path[9][370000];

int lev[] = {1,1,2,6,24,120,720,5040,40320,362880};
int cantor(int s[9])
{
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*lev[9 - i - 1];
}
return sum + 1;
}
void find_path(int pos,int e)
{
long long road = path[pos][e];
stack<int> sta;
int a;
for(int i = 0;i<vis[pos][e] - 1;i++)
{
a = road%4;
road = road>>2;
sta.push(a);
}
while(!sta.empty())
{
a = sta.top();sta.pop();
printf("%c",dir[a]);
}
printf("\n");

}
void bfs(int pos)
{
int head = 0,tail = 0;
n[0].fa = 0;
n[0].d = '\0';
n[0].loc = pos;
n[0].state = cantor(n[0].s);
vis[pos][n[0].state] = 1;
Node cur;
while(head <= tail)
{
cur = n[head];
//if(pos == 6) printf("Cur loc:: %d\n",cur.loc);
int x = cur.loc / 3;
int y = cur.loc % 3;
for(int i = 0 ;i < 4;i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if(nx>=0&&ny>=0&&nx<3&&ny<3)
{
Node nex = cur;
nex.fa = head;
nex.s[cur.loc] = nex.s[nx*3 + ny];
nex.loc = nx*3 + ny;
nex.s[nex.loc] = 0;
nex.state = cantor(nex.s);

if(!vis[pos][nex.state])
{
vis[pos][nex.state] = vis[pos][cur.state] + 1;
path[pos][nex.state] = (path[pos][cur.state]<<2) + i;
//if(pos == 6) printf("Nex loc:: %d\n",nex.loc);
n[++tail] = nex;
}
}
}
head++;
}
}

void init(int pos)
{
for(int i = 0,j = 1;i<9;i++)
{
if(i == pos)//pos代表X的位置
{
n[0].s[i] = 0;//x用0表示
}
else
{
n[0].s[i] = j++;
}
}
//printf("POS :: %d\n",pos);
bfs(pos);
}

int main()
{
int T,t;
int exc[10];
char src[10];
char des[10];
memset(path,0,sizeof path);
memset(vis,0,sizeof vis);
for(int i = 0;i<9;i++)
{
init(i);
}
scanf("%d",&T);
t = T;
while(T--){
scanf("%s",src);
int pos = 0;
for(int i = 0,j = 1;i<9;i++)
{
if(src[i] == 'X'){
src[i] = '0';
pos = i;
exc[0] = 0;
}
else
{
exc[src[i] - '0'] = j++;
}
}
scanf("%s",des);
int s[9];
for(int i = 0;i<9;i++)
{
if(des[i] == 'X')
{
s[i] = 0;
}
else
{
s[i] = exc[des[i] - '0'];
}
}
int tt = cantor(s);
printf("Case %d: %d\n",t-T,vis[pos][tt] - 1);
find_path(pos,tt);
}
return 0;
}

HDU - 3567的更多相关文章

  1. HDU 3567 Eight II(八数码 II)

    HDU 3567 Eight II(八数码 II) /65536 K (Java/Others)   Problem Description - 题目描述 Eight-puzzle, which is ...

  2. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  3. hdu 1430+hdu 3567(预处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路:由于只是8种颜色,所以标号就无所谓了,对起始状态重新修改标号为 12345678,对目标状 ...

  4. HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

    http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...

  5. HDU 3567 Eight II

    Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 3 ...

  6. HDU 3567 Eight II BFS预处理

    题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么 分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法 预处理打表,因为八数码问 ...

  7. HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二

    类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...

  8. HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二

    这题难度颇大啊,TLE一天了,测试数据组数太多了.双向广度优先搜索不能得到字典序最小的,一直WA. 思路:利用IDA*算法,当前状态到达目标状态的可能最小步数就是曼哈顿距离,用于搜索中的剪枝.下次搜索 ...

  9. Eight II HDU - 3567

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

随机推荐

  1. Linux 系统的总管 Systemd

    目录 1. init的进化,全功能的Systemd 2 1.1 Linux系统中,init主要有3个版本 2 1.2 比较传统的init程序,Systemd的特点有: 2 1.3 Systemd Jo ...

  2. 一次奇妙的http请求之旅

    TCP/IP不是一个协议,而是一个协议族的统称.里面包括IP协议.IMCP协议.TCP协议. 这里有几个需要注意的知识点: 互联网地址:也就是IP地址,一般为网络号+子网号+主机号 域名系统:通俗的来 ...

  3. 添加ssl证书

    ssl证书会使你的网站更加安全,防止isp在你的网站显示时添加广告,浏览网页时地址栏左边有一个绿色安全的图标,使用户感觉更加安全放心. 颁发ssl证书的机构很多,有收费的,也有免费的.当然对于自己的小 ...

  4. 出现 OSError: symbolic link privilege not held的解决方案

    jupyter notebook  出现 OSError: symbolic link privilege not held问题时  以管理员方式重新打开prompt.

  5. RPC概念及分类【转载】

    RPC概念及分类 RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”.目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用 ...

  6. dbca建库--linux上使用vnc图形化安装oracle10g版本

    选择创建数据库 配不配置em,自己决定,我们选择配置 配置下面账户密码,在项目中,下面账户肯定是不相同的,我们这里输入相同的,密码为oracle10g 选择文件系统存放(asm和字符设备暂时不能存放) ...

  7. Django学习笔记之数据库-模型的操作

    模型的操作 在ORM框架中,所有模型相关的操作,比如添加/删除等.其实都是映射到数据库中一条数据的操作.因此模型操作也就是数据库表中数据的操作. 添加模型 添加模型到数据库中.首先需要创建一个模型.创 ...

  8. java-log4j日志打印

    参考路径: https://blog.csdn.net/edward0830ly/article/details/8250412 https://www.cnblogs.com/ITtangtang/ ...

  9. MUI在项目中使用时遇到的问题的个人分享

    picker 添加年插件问题总结 1. 取消按钮点击事件无法获取 可以获取到取消按钮标签和确定按钮标签 但是只能获取去顶按钮事件,取消点击事件无法获取 通过判断picker的display状态也不能确 ...

  10. failed: dlopen failed: cannot locate symbol

    修改proj.android/jni/Application.mk 添加:APP_PLATFORM := android-19