逆向bfs搜索打表+康拓判重
HDU 1043八数码问题
八数码,就是1~8加上一个空格的九宫格,这道题以及这个游戏的目标就是把九宫格还原到从左到右从上到下是1~8然后最后是空格。
没了解康托展开之前,这道题怎么想都觉得很棘手,直接搜索的话也不知道怎么剪枝,而且判重也不可能开一个9维的数组,空间也不允许,所以先了解康托展开是无可厚非的第一步,这里就引用一下大佬的介绍,很简单很实用的关于全排列的一个东西
学会康托展开之后这道题就有很多解法了,很多是用A*的,不过这个我还没学会,只能弱弱的用万能的搜索来暴力过一切了,当然搜索的做法也有几个,直接暴力的正向搜索单组测试数据是可以的,单多组测试数据的话还是会超时,还有种双向bfs的做法,也就是把当前的数列和我们要的目标数列同时加入队列,然后两个相遇时就可以了。
不过我个人觉得那两个写起来比较麻烦不好处理,所以我还是采用一个逆向的bfs来打表,为什么可以打表的,了解康托展开后我们可以知道,这题的全排列最多也就9!,那我们完全可以预处理一下,由目标状态去跑到其他状态,把每个状态的康托展开的值作为它的一个编号,由此打表,具体的如代码
#include<cstdio>
#include<queue>
using namespace std;
const int dir[][]={{,},{,},{,-},{-,}};
const char leg[]={'l','u','r','d'};//因为是逆回去的,所以方向是反的
char s[];
int jc[]={},sm[];
struct Way{
char ans;
int f;
Way(){
f=-;
}
}w[];
struct Node{
int num[];
int kt,p;//康托值,x的位置
};
int kangtuo(int *a)//康托展开
{
int ans=;
for(int i=;i<;i++)
{
int k=;
for(int j=i+;j<;j++)
if(a[i]>a[j])
k++;
ans+=k*jc[-i];
}
return ans;
}
void bfs()
{
queue<Node> q;
Node b;
for(int i=;i<;i++)
b.num[i]=i;
b.kt=,b.p=;
q.push(b);
while(!q.empty())
{
Node e=q.front();
q.pop();
for(int i=;i<;i++)
{
int dx=e.p/+dir[i][];//二维比价好处理位置变化
int dy=e.p%+dir[i][];
if(dx>=&&dx<&&dy>=&&dy<)
{
b=e;b.p=dx*+dy;
int t=b.num[e.p];b.num[e.p]=b.num[b.p];b.num[b.p]=t;
b.kt=kangtuo(b.num);
if(w[b.kt].f==-)
{
w[b.kt].f=e.kt;
w[b.kt].ans=leg[i];
q.push(b);
}
}
}
}
}
int main()
{
for(int i=;i<=;i++)
jc[i]=jc[i-]*i;
bfs();
while(~scanf("%s",s))
{
for(int i=;i<;i++)
scanf("%s",s+i);
for(int i=;i<;i++)
if(s[i]>=''&&s[i]<='')
sm[i]=s[i]-'';
else
sm[i]=;
int kt=kangtuo(sm);
if(w[kt].f==-)//没遍历到这个状态
printf("unsolvable\n");
else
{
while(kt)//回溯输出答案
{
printf("%c",w[kt].ans);
kt=w[kt].f;
}
printf("\n");
}
}
return ;
}
代码千万条,自觉第一条,复制粘贴爽,打铁泪两行
既然涉及到八数码,最后再补充一个结论,怎么直接判断八数码有没有解,这涉及到逆序数,目标状态1~8的逆序数是0,而上下左右的变换并不会改变逆序数的奇偶性,(这里说的逆序数是不计x的)
所以结论就是,序列的奇偶性要和目标状态一致。
逆向bfs搜索打表+康拓判重的更多相关文章
- 八数码问题+路径寻找问题+bfs(隐式图的判重操作)
Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...
- hdu 5012 bfs --- 慎用STL 比方MAP判重
http://acm.hdu.edu.cn/showproblem.php?pid=5012 发现一个问题 假设Sting s = '1'+'2'+'3'; s!="123"!!! ...
- poj3635 FULL tank(TLE) 有限制的最短路(BFS搜索)。
用的BFS+优先队列+二进制压缩状态判重+链式前向星, TLE,好像有人这样过了...好像要用A*算法,还不太会,所以暂时放弃.但是也学会了很多,学习了链式前向星,更深理解了BFS求最优的时候,什么时 ...
- BFS(四):搜索状态判重
在采用广度优先算法进行搜索时,一个需要重点注意的是在搜索过程中判重和去重.前面介绍的几个例子中,判重都较简单,如采用vis[]数组,若vis[i]==0,则i未访问过,i入队列:若vis[i]!=0, ...
- UVA 10651 Pebble Solitaire(bfs + 哈希判重(记忆化搜索?))
Problem A Pebble Solitaire Input: standard input Output: standard output Time Limit: 1 second Pebble ...
- BFS以及hash表判重的应用~
主要还是讲下hash判重的问题吧 这道题目用的是除法求余散列方式 前几天看了下算法导论 由于我们用的是线性再寻址的方式来解决冲突问题 所以hash表的大小(余数的范围)要包含我们要求的范围 对mod的 ...
- poj 1077-Eight(八数码+逆向bfs打表)
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...
- hdu 4444 Walk (离散化+建图+bfs+三维判重 好题)
Walk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...
- HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
随机推荐
- 线段树维护动态连续子段HDU1540
题意:http://acm.hdu.edu.cn/showproblem.php?pid=1540 #define IOS ios_base::sync_with_stdio(0); cin.tie( ...
- Photon Server 实现注册与登录(一) --- Hibernate整合到项目中
本系列实现目的:基于Photon Server实现注册于登录 一.拷贝Nbibernate项目的文件到MyGamerServer项目中. 二.数据库新建表,结构如下 三.修改文件名和配置 (1).将拷 ...
- k8s-helm安装
kubernetes 1.15安装部署helm插件 简单介绍: Helm其实就是一个基于Kubernetes的程序包(资源包)管理器,它将一个应用的相关资源组织成为Charts,并通过Charts ...
- springboot由于bean加载顺序导致的问题
先记录现象: dubbo整合zipkin时,我的配置文件是这样的 @Bean("okHttpSender") public OkHttpSenderFactoryBean okHt ...
- 基于SDP的提议/应答(offer/answer)模型简介
1.引入 在松耦合会议中,会话参数完全由会议创建者来确定,参与者能做的仅仅是根据这些会话参数来加入会议(当然也可以选择不加入).这种情况下,主要要做的就是会话描述,在这里SDP本身就足够了. 但是在更 ...
- sipp如何避免dead call
uac 和 uas 都加上 -deadcall_wait 0
- CSP-S2019「Symphony」
NOTICE:如觉得本文有什么错误或不妥之处,欢迎评论区以及私信交流,反对乱喷,如有一些让人不爽的评论或人身攻击,带来的后果本人一律不负责 准备工作 Day-inf~Day-3 000 every d ...
- 安卓开发之获取SD卡空间数据
package com.lidaochen.getsdcardspace; import android.os.Environment; import android.support.v7.app.A ...
- JavaSpring【二、IOC】
概述: 接口及面向接口编程 接口:用于沟通的中介物的抽象,实体把自己提供给外界的方法的抽象化说明,将声明和实现分离,使其能够改变内部而不影响与外部的交互方式 面向接口编程:在结构设计中,分清层次及调用 ...
- Srping事物的隔离策略
spring事务: 什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 事务特性(4种): 原子性 (atomicity):强调事务的不可分割. 一致性 (c ...