http://acm.hdu.edu.cn/showproblem.php?pid=1043

由于HDU这里的涉及多组数据,而每组数据按照一般的bfs()做法,即遍历每一种可行方案都保存一次路径,直到找到解就停下来,需要100+ms,这种做法放在多组数据中可能会超时,因此,不如我们只花100+ms来只做一次遍历,预先把所有能到达的状态找到并把路径记录下来,存放到char path[ ][ ]中,然后来一组数据就直接判断是否有这样的状态再进行输出(前面的也就是打表啦Σ(っ °Д °;)っ),大体上和一般的bfs()做法一样,可以使用队列,也可以使用循环自己模拟,主要问题是需要保存的状态是一个3 x 3 的矩阵,如果想要对每一种不同的序列都进行标记去重的话,选择康托展开那样的会很方便,就是说,通过某种线性变换运算(口糊),将这个 矩 阵 唯一的变成一个 对应的 实数,然后只用一维数组 (bool vis[ ])就可以进行状态标记了,嗯。具体康托展开什么的网上的讲解也有很多,本质是十进制转换为八进制,下面是在HDU上的ac代码:

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

int arr[3][3];
int vis[400000];
char path[400000][40];
int lev[] = {1,1,2,6,24,120,720,5040,40320,362880};
int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};
char dir[] = "durl";
int len;
struct node{
int s[9];
int loc;
int state;
int fa;
char d;
}n[400000];

int Inverse_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(node end)
{
int state = end.state;
int f = end.fa;
len = 0;
path[state][len++] = end.d;
while(f)
{
path[state][len++] = n[f].d;
f = n[f].fa;
}
}

void bfs(){
memset(vis, 0,sizeof vis);
node nex;
int head = 0,tail = 0;
for(int i = 0;i<8;i++)
n[0].s[i] = i+1;
n[0].s[8] = 0;
n[0].loc = 8;
n[0].state = 46234;
vis[46234] = 1;
while(head<=tail)
{
int x = n[head].loc / 3;
int y = n[head].loc % 3;
for(int i = 0;i<4;i++)
{
int tx = x + dx[i];
int ty = y + dy[i];
if(tx < 0 || tx>2||ty<0||ty>2) continue;

nex = n[head];
nex.loc = tx*3 + ty;
nex.s[n[head].loc] = nex.s[nex.loc];
nex.s[nex.loc] = 0;
nex.fa = head;
nex.d = dir[i];
nex.state = Inverse_cantor(nex.s);
if(!vis[nex.state])
{
vis[nex.state] = 1;
find_path(nex);
n[++tail] = nex;
}
}
head++;
}
}

int main()
{
bfs();
char ch[3];
node cur;
while(~scanf("%s",ch))
{
if(!strcmp(ch,"x"))
{
cur.s[0] = 0,cur.loc = 0;
}
else
{
cur.s[0] = ch[0] - '0';
}

for(int i = 1;i<9;i++)
{
scanf("%s",ch);
if(!strcmp(ch,"x"))
{
cur.s[i] = 0,cur.loc = i;
}
else
{
cur.s[i] = ch[0] - '0';
}
}
cur.state = Inverse_cantor(cur.s);
if(vis[cur.state])
printf("%s\n",path[cur.state]);
else
printf("unsolvable\n");
}
return 0;
}

HU-1043的更多相关文章

  1. HU 参考错误修正:/SCWM/RCORR_HUREF

    HU 参考错误修正:report: /SCWM/RCORR_HUREF HU 参考的ODO/ID的凭证号及行项目号不正确的修正程序.

  2. 【BZOJ】1043: [HAOI2008]下落的圆盘(计算几何基础+贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1043 唯一让我不会的就是怎么求圆的周长并QAAQ... 然后发现好神!我们可以将圆弧变成$[0, 2 ...

  3. 形状特征提取-Hu不变矩(转载)

    [原文部分转载]:http://blog.csdn.net/wrj19860202/archive/2011/04/16/6327094.aspx 在连续情况下,图像函数为 ,那么图像的p+q阶几何矩 ...

  4. 51nod 1043 幸运号码(数位dp)

    题目链接:51nod 1043 幸运号码 题解:dp[i][j]表示 i 个数和为 j 的总数(包含0开头情况) dp[i][j] = dp[i-1][j-k] i & 1 :这里用滚动数组节 ...

  5. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  6. 二分--1043 - Triangle Partitioning

    1043 - Triangle Partitioning PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit:  ...

  7. hdu 1043 Eight 经典八数码问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...

  8. hihoCoder 1043 完全背包 (dp)

    http://hihocoder.com/problemset/problem/1043 动态转移方程 :for v=cost..V f[v]=max(f[v],f[v-c[i]]+w[i]); #i ...

  9. 1043. Is It a Binary Search Tree (25)

    the problem is from pat,which website is http://pat.zju.edu.cn/contests/pat-a-practise/1043 and the ...

  10. hihocoder 1043 完全背包

    #1043 : 完全背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的 ...

随机推荐

  1. Unity 常用插件1

    作者:Meta42链接:https://www.zhihu.com/question/29097415/answer/229015898来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

  2. 学习笔记DL003:神经网络第二、三次浪潮,数据量、模型规模,精度、复杂度,对现实世界冲击

    神经科学,依靠单一深度学习算法解决不同任务.视觉信号传送到听觉区域,大脑听学习处理区域学会“看”(Von Melchner et al., 2000).计算单元互相作用变智能.新认知机(Fukushi ...

  3. admin-4

    每个学员机上有三台预先配置好的虚拟机server —— 作为练习用服务器desktop —— 作为练习用客户机classroom —— 提供网关/DNS/软件素材等资源 通过真机上“虚拟系统管理器”访 ...

  4. Linux第八节课学习笔记

    su命令可以切换用户身份,一般不用,而是用sudo. visudo命令中可执行命令列表不用ALL,我们可以先使用whereis命令找出命令所对应的保存路径,然后把配置文件第99行的用户权限参数修改成对 ...

  5. 跳台阶(JAVA)

    跳台阶 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 思路:典型的动态规划问题,动态规划问题最关键的是把事件中的各种情形抽象为状态,然后找到前后 ...

  6. C语言题库----指针

    1.如果f是一个函数,请说明 f() 和f的意思. f是函数的地址,f()是函数 2.怎样理解数组的下标运算? 先偏移,后取址. 3.int *p,*q; int a[]={10,20,30,40}; ...

  7. Vue面试中经常会被问到的面试题

    一.对于MVVM的理解 MVVM是 Model-View-ViewModel 的缩写. Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑. View代表UI组件,它负责将数据模 ...

  8. JS 实现Table相同行的单元格自动合并示例代码

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...

  9. HQL详解

    HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此 Hib ...

  10. RocketMQ基本概念及原理介绍

    基本概念 ProducerGroup 通常具有同样属性(处理的消息种类-topic.以及消息处理逻辑流程—分布式多个客户端)的一些producer可以归为同一个group.在事务消息机制中,如果某条发 ...