Eight
Eight
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043/http://acm.split.hdu.edu.cn/showproblem.php?pid=1043
IDA*
八数码问题直接dfs/bfs,时间复杂度很高,需要一个很好的剪枝,使用IDA*。当前状态到达目标状态最短(理想)距离h是各个数字直接到达目的地,如果h+当前步数>最深搜索的步数,那么这种情况就不去考虑。对于判断八数码是否可解,需要用到逆序数的知识((╯‵□′)╯︵┻━┻这谁会知道啊):x的移动并不影响整个数列逆序数的奇偶性,也就是说若给定初始状态逆序数的奇偶性与目标状态不同,则unsolvable。去重用到了状态压缩,因为数字数量级为10^9,使用set/map存储状态。(坑点是多组数据,但是题目没说)
代码如下:
#include<cstdio>
#include<cmath>
#include<iostream>
#include<set>
using namespace std;
const int standard=;
set<int>exist;
int a[],state[][],deep,sx,sy,step[];
char c;
int dx[]={,,-,};
int dy[]={-,,,};
char towards[]={'l','r','u','d'};
int index;
bool ok=;
int inversions(){//求逆序数
int num=;
for(int i=;i<;++i)
for(int j=i+;j<;++j)
if(a[i]!=&&a[j]!=)
if(a[j]<a[i])num++;
return num;
}
int zip(){
int s=;
for(int i=;i<;++i)
for(int j=;j<;++j)
s=s*+state[i][j];
return s;
}
int Astar(){//无视障碍物直接到达目的地所需步数
int h=;
for(int i=;i<;++i)
for(int j=;j<;++j){
int num=state[i][j];
if(num!=){
int x=(num-)/;
int y=(num-)%;
h+=abs(x-i)+abs(y-j);
}
}
return h;
}
void IDAstar(int px,int py,int nowdeep){
if(ok)return;
int h=Astar();
if(!h&&zip()==standard){
ok=;
return;
}
if(nowdeep+h>deep)return;//A*估价函数
for(int i=;i<;++i){
int x=px+dx[i];
int y=py+dy[i];
if(<=x&&x<&&<=y&&y<){
swap(state[px][py],state[x][y]);
int s=zip();
if(!exist.count(s)){
step[index++]=i;
exist.insert(s);
IDAstar(x,y,nowdeep+);
if(ok)return;
exist.erase(s);
step[--index]=;
}
swap(state[px][py],state[x][y]);
}
}
}
int main(void){
char k;
while(cin>>k){
ok=;
index=;
for(int i=;i<;++i){
if(i==)c=k;
else cin>>c;
if(''<=c&&c<='')
a[i]=c-'';
else a[i]=;
}
if(inversions()&){//若有解,逆序数的奇偶性和standard相同
cout<<"unsolvable"<<endl;
continue;
}
for(int i=;i<;++i)
for(int j=;j<;++j){
state[i][j]=a[*i+j];
if(state[i][j]==)
sx=i,sy=j;
}
int s=zip();
if(s==standard){
cout<<""<<endl;
continue;
}
for(deep=;!ok;++deep){
exist.clear();
exist.insert(s);
IDAstar(sx,sy,);
}
for(int i=;i<index;++i)
cout<<towards[step[i]];
cout<<""<<endl;
}
}
随机推荐
- 在Node.js中使用RabbitMQ系列一 Hello world
在前一篇文章中可伸缩架构简短系列中提到过关于异步的问题.当时推荐使用RabbitMQ来做任务队列的实现方案.本篇文章以Node.js为例子,来实际操作如何和RabbitMQ进行交互. 介绍 Rabbi ...
- [ios]iphone 获取UIWebView内Html方法
原文:http://blog.csdn.net/diyagoanyhacker/article/details/6564897 获取所有html:NSString *lJs = @"docu ...
- Maven之pom.xml 配置详解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 用备份控制文件做不完全恢复下的完全恢复(数据文件备份<旧>--新建表空间--控制文件备份<次新>--日志归档文件<新>)
为什么会使用备份的控制文件? 实际工作中主要有两种情况:第一种:当前控制文件全部损坏,而数据文件备份,控制文件备份及当前日志处于不同SCN版本,它们之间又增加过表空间(数据文件).第二种:当前控制文件 ...
- Matlab最新的官方文档中文翻译
文章翻译的是Matlab最新的官方文档R2016b,可能后续如果我还有时间会继续翻译,希望能够帮到大家,翻译的不好请大家不要吐槽. Matlab官方文档地址:http://cn.mathworks.c ...
- <hdu - 1272> 小希的迷宫 并查集问题 (注意特殊情况)
本题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272 Problem Description: 上次Gardon的迷宫城堡小希玩了很久(见Probl ...
- Java中不定参的使用规则
Java中有时候会使用到不定参数,它的使用规则有2项: 一个方法中只能使用一个不定参数. 不定参数必须是方法中最后一个参数. 不定参数在传入的过程中会行成一个数组传入,如果不会放在最后一个,虚拟机无法 ...
- Attribute的理解和认识
1什么是Attribute? 在网上看到这样一段定义 MADN的定义为:公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法和属性等.A ...
- 给RelativeLayout设置背景,无效果bug解决
drawable文件夹下面 tomyshop_selector.xml文件 <?xml version="1.0" encoding="utf-8"?&g ...
- CodeForces 675E Trains and Statistic
贪心,递推,线段树,$RMQ$. 假设我们记$ans[i]$是以$i$点为起点对答案的贡献,那么答案就是$\sum\limits_{i = 1}^n {ans[i]}$. $ans[i]$怎么计算呢? ...