POJ1077 Eight —— IDA*算法
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html
代码一:像BFS那样,把棋盘数组放在结构体中。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+;
#define AIM 1 //123456789的哈希值为1 struct node
{
int s[];
int loc;
}; int fac[] = { , , , , , , , , };
int dir[][] = { -,, ,, ,-, , };
char op[] = {'u', 'd', 'l', 'r' }; int cantor(int s[]) //获得哈希函数值
{
int sum = ;
for(int i = ; i<; i++)
{
int num = ;
for(int j = i+; j<; j++)
if(s[j]<s[i]) num++;
sum += num*fac[-i];
}
return sum+;
} int dis_h(int s[]) //获得曼哈顿距离
{
int dis = ;
for(int i = ; i<; i++)
if(s[i]!=)
{
int x = i/, y = i%;
int xx = (s[i]-)/, yy = (s[i]-)%;
dis += abs(x-xx) + abs(y-yy);
}
return dis;
} char path[];
bool IDAstar(node now, int depth, int pre, int limit)
{
if(dis_h(now.s)==) //搜到123456789
{
path[depth] = '\0';
puts(path);
return true;
} int x = now.loc/;
int y = now.loc%;
for(int i = ; i<; i++)
{
if(i+pre== || i+pre==) continue; //方向与上一步相反, 剪枝
int xx = x + dir[i][];
int yy = y + dir[i][];
if(xx>= && xx<= && yy>= && yy<=)
{
node tmp = now;
tmp.s[x*+y] = tmp.s[xx*+yy];
tmp.s[xx*+yy] = ;
tmp.loc = xx*+yy;
path[depth] = op[i];
if(depth++dis_h(tmp.s)<=limit) //在限制内
if(IDAstar(tmp, depth+, i, limit))
return true;
}
}
return false;
} int main()
{
char str[];
while(gets(str))
{
node now;
int cnt = ;
for(int i = ; str[i]; i++)
{
if(str[i]==' ') continue;
if(str[i]=='x') now.s[cnt] = , now.loc = cnt++;
else now.s[cnt++] = str[i]-'';
} int limit;
for(limit = ; limit<=; limit++) //迭代加深搜
if(IDAstar(now, , INF, limit))
break;
if(limit>)
puts("unsolvable");
}
}
代码二:根据DFS的特点,由于棋盘每次只交换一对,所以可以只开一个棋盘数组。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e6+; int M[];
int fac[] = { , , , , , , , , };
int dir[][] = { -,, ,, ,-, , };
char op[] = {'u', 'd', 'l', 'r' }; int cantor(int s[]) //获得哈希函数值
{
int sum = ;
for(int i = ; i<; i++)
{
int num = ;
for(int j = i+; j<; j++)
if(s[j]<s[i]) num++;
sum += num*fac[-i];
}
return sum+;
} int dis_h(int s[]) //获得曼哈顿距离
{
int dis = ;
for(int i = ; i<; i++)
if(s[i]!=)
{
int x = i/, y = i%;
int xx = (s[i]-)/, yy = (s[i]-)%;
dis += abs(x-xx) + abs(y-yy);
}
return dis;
} char path[];
bool IDAstar(int loc, int depth, int pre, int limit)
{
int h = dis_h(M);
if(depth+h>limit)
return false; if(h==) //搜到123456789
{
path[depth] = '\0';
puts(path);
return true;
} int x = loc/;
int y = loc%;
for(int i = ; i<; i++)
{
if(i+pre== || i+pre==) continue; //方向与上一步相反, 剪枝
int xx = x + dir[i][];
int yy = y + dir[i][];
if(xx>= && xx<= && yy>= && yy<=)
{
swap(M[loc], M[xx*+yy]);
path[depth] = op[i];
if(IDAstar(xx*+yy, depth+, i, limit))
return true;
swap(M[loc], M[xx*+yy]);
}
}
return false;
} int main()
{
char str[];
while(gets(str))
{
int cnt = , loc;
for(int i = ; str[i]; i++)
{
if(str[i]==' ') continue;
if(str[i]=='x') M[cnt] = , loc = cnt++;
else M[cnt++] = str[i]-'';
} int limit;
for(limit = ; limit<=; limit++) //迭代加深搜
if(IDAstar(loc, , INF, limit))
break;
if(limit>)
puts("unsolvable");
}
}
POJ1077 Eight —— IDA*算法的更多相关文章
- HDU3567 Eight II —— IDA*算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others) ...
- 【学时总结】 ◆学时·II◆ IDA*算法
[学时·II] IDA*算法 ■基本策略■ 如果状态数量太多了,优先队列也难以承受:不妨再回头看DFS-- A*算法是BFS的升级,那么IDA*算法是对A*算法的再优化,同时也是对迭代加深搜索(IDF ...
- HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法
先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...
- 八数码(IDA*算法)
八数码 IDA*就是迭代加深和A*估价的结合 在迭代加深的过程中,用估计函数剪枝优化 并以比较优秀的顺序进行扩展,保证最早搜到最优解 需要空间比较小,有时跑得比A*还要快 #include<io ...
- HDU1560 DNA sequence —— IDA*算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Oth ...
- POJ1077 Eight —— A*算法
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 关于A*算法:g(n)表示从起点到任意节点n的路径花费,h(n)表示从节点n到目标节点路径花费 ...
- IDA*算法——骑士精神
例题 骑士精神 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者 ...
- UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)
题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n.剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列. 分析: 1.IDA*搜索:maxn是dfs的层数上限,若 ...
- 还不会ida*算法?看完这篇或许能理解点。
IDA* 算法分析 IDA* 本质上就是带有估价函数和迭代加深优化的dfs与,A * 相似A *的本质便是带 有估价函数的bfs,估价函数是什么呢?估价函数顾名思义,就是估计由目前状态达 到目标状态的 ...
随机推荐
- Laravel5.1 报错:控制器不存在
Laravel5.1 报错:控制器不存在 错误提示: Class App\Http\Controllers\Api/UserController does not exist 解决: (1)检查控制器 ...
- rman备份OBSOLETE和EXPIRED参数来历及区别
http://blog.itpub.net/30496894/viewspace-2096221/
- 2018 ICPC 徐州网络预赛 Features Track (STL map pair)
[传送门]https://nanti.jisuanke.com/t/31458 [题目大意]有N个帧,每帧有K个动作特征,每个特征用一个向量表示(x,y).两个特征相同当且仅当他们在不同的帧中出现且向 ...
- luogu P2296 寻找道路
题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...
- bzoj 2694: Lcm
2694: Lcm Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 422 Solved: 220[Submit][Status][Discuss] ...
- java jvm学习
在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...
- 如何使用RDP跳过网络隔离?
简介 本文我将向大家演示,如何通过RDP跳转盒进入隔离/受保护的网络.下图是我为该场景制作的拓扑图: 简要说明: LAN是一种扁平的工作站和服务器网络. 一些服务器(包括RDP跳转盒)无法与Inter ...
- 数据库系统学习(七)-SQL语言之复杂查询与视图
第七讲 SQL语言之复杂查询与视图 基本内容 子查询 IN与NOT IN谓词子查询 判断某一表达式的值是否在子查询的结构中 非相关子查询 相关子查询 theta some /theta all谓词子查 ...
- 【JavaScript】数据类型
学习不论什么一种程序设计语言.数据类型都是不可缺少的一部分内容,非常基础,也非常重要.该用何种数据类型定义变量.这也是编程中最基础的一项. ECMAScript中有5种简单数据类型:Undefined ...
- 系统重装 WIN7如何创建和使用VHD文件
1 在磁盘管理中,点击操作-创建VHD,然后可以创建一个空的VHD文件 2 右击这个磁盘,点击初始化磁盘,然后可以新建简单卷 3 右击这个磁盘,设置为脱机或者联机就可以在计算机中显示和隐藏这个 ...