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,估价函数是什么呢?估价函数顾名思义,就是估计由目前状态达 到目标状态的 ...
随机推荐
- 洛谷 [P3205] 合唱队
区间DP 手动模拟一下,我们发现本题就是一个左右加数的区间DP #include <iostream> #include <cstdio> #include <cstri ...
- 树状数组求第K大(From CLJ)
; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;
- [UIScreen mainScreen].applicationFrame与[UIScreen mainScreen].bounds区别
[UIScreen mainScreen].applicationFrame与[UIScreen mainScreen].bounds区别: applicationFrame会自动判断是否存在状态栏, ...
- Yii 安装学习
(1)打开yii官方网站: http://www.yiichina.com (2)点击下载,跳转到下载页面: (3)找到从归档文件安装,新手学习,使用[ Yii2的基本应用程序模板]: (4)下载解压 ...
- elasticsearch入门使用(四) 索引、安装IK分词器及增删改查数据
一.查看.创建索引 创建一个名字为user索引: curl -X PUT 'localhost:9200/stu' {"acknowledged":true,"shard ...
- LR(1)文法分析器 //c++ 实现
1.先读入终结符,非终结符,和所有产生式. 2.预处理:初始化:getpp()获得每个非终结符在产生式左边时的产生式编号, 记录在 string getp[]中(可以多个). 3.获得所有的符号的fi ...
- Windows下,RabbitMQ安装、卸载以及遇到的坑
RabbitMQ是目前比较使用比较广泛的一个队列服务器,但是很多朋友在使用过程中,也遇到一些问题,这篇文章主要是做一个总结吧 本篇文章,虽然标题命名为“安装与卸载”,但是网上有很多类似的文章,我就简单 ...
- java连oracle
下载连接驱动 安装完oracle之后 D:\app\Administrator\product\11.2.0\dbhome_1\jdbc\lib 目录下拷贝 支持jdk1.6以上 From.java ...
- T2038 香甜的黄油 codevs
http://codevs.cn/problem/2038/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 农夫John ...
- chmod u g x o 777
chmod [ugoa] [+-= ] [rwx] 文件或者是目录u:表示文件的属主,g:表文件的属组内的成员,o:则表示其它用户,a:是所有用户的(ugo的总和)+—=:是对权限的操作,+表示增加相 ...