HDU - 3567
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的更多相关文章
- HDU 3567 Eight II(八数码 II)
HDU 3567 Eight II(八数码 II) /65536 K (Java/Others) Problem Description - 题目描述 Eight-puzzle, which is ...
- POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...
- hdu 1430+hdu 3567(预处理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路:由于只是8种颜色,所以标号就无所谓了,对起始状态重新修改标号为 12345678,对目标状 ...
- HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...
- HDU 3567 Eight II
Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 3 ...
- HDU 3567 Eight II BFS预处理
题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么 分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法 预处理打表,因为八数码问 ...
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...
- HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二
这题难度颇大啊,TLE一天了,测试数据组数太多了.双向广度优先搜索不能得到字典序最小的,一直WA. 思路:利用IDA*算法,当前状态到达目标状态的可能最小步数就是曼哈顿距离,用于搜索中的剪枝.下次搜索 ...
- Eight II HDU - 3567
Eight II Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 130000/65536 K (Java/Others)Total S ...
随机推荐
- js+ajax编码三级联动
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title> ...
- 例:三位老师对某次数学竞赛进行了预测,他们的预测如下: 甲:学生A得了第一名,学生B得第三名。 乙:学生C得了第一名,学生D得第四名。 丙:学生D得了第二名,学生A得第三名。 结果表明,他们都说对了一半,说错了一半,并且无并列名次,输出A、B、C和D各自的名次。
public class demo { public static void main(String[] args) { int a,b,c,d;//代表四个学生 boolean x1,x2,x3;/ ...
- 安装FireEye渗透测试套件commando-vm
前两天FireEye开源了套他们自己的渗透测试工具,玩了下,这里简单讲一下我安装的过程. 1.首先是虚拟机,在virtualbox或者vmware中安装一个新的Windows系统,win7或者win1 ...
- 芯灵思Sinlinx A64开发板设置qt程序自启动
开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 对于开发板开机启动程序的设置可以这样做通过串口连接开发板 v ...
- jumpserver管理入门
比较规范一点的步骤 1.先在用户管理查看用户组里,添加用户组 2.在用户管理查看用户里,添加用户 3.在资产管理里查看资产,添加资产.在批量增加那里可以使用表格快速导入添加 4.在授权管理里的系统用户 ...
- Ansible 安装与配置(一)
公司大概有200多云主机需要进行管理,但是如果通过手工管理费时还累最终结果也容易出错,所以考虑通过自动化的方式来管理云主机,目前开源的自动化工具,大家用的比较多的有Ansible和Saltstack这 ...
- [ZZ] 用matlab绘制箭头
用matlab绘制箭头 http://npfeng900.blog.163.com/blog/static/14456108201221922944998/ 用matlab绘制箭头1 用matlab绘 ...
- windows使用ruby配置redis集群
基本是从网上抄的.不过网上的东西不一定是完全正确的 我修正了一下 首先,资源有限,我就不搞什么主机从机了,我需要的集群实现内存的最大化 四台机器安装redis, 配置成服务, 打开6379端口,集群1 ...
- 基于STM8的ADC读取---STM8-第四章
1. 综诉 想学会如何在STM8上使用ADC这个功能,我们先得了解单片机中ADC究竟是什么. ADC是模拟信号转成数值信号,单片机只能识别TTL电平,其实就是 1 或者 0 ,但是如果我们给它一个3. ...
- LeetCode【112. 路径总和】
思路就是从根节点开始向下选节点,依次与sum比较大小,若小,则向下选左右节点其中一个,若大,则接下来判断是否是叶子节点,若是,则返回false 若不是,则上一步选另一节点,再将上述重新执行. 对于叶子 ...