Codevs1225 八数码难题
2015-08-20 17:13
302 查看
题目大意:在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
思路:使用IDA*算法。估价函数为现在棋盘与目标棋盘的对应元素不同的个数。剪枝:若当前深度加上估价函数值大于限定的深度则剪枝。搜索时,每次拿出估价函数最小的节点进行扩展,这一操作利用优先队列支持。整体上属于广搜。
代码如下:
思路:使用IDA*算法。估价函数为现在棋盘与目标棋盘的对应元素不同的个数。剪枝:若当前深度加上估价函数值大于限定的深度则剪枝。搜索时,每次拿出估价函数最小的节点进行扩展,这一操作利用优先队列支持。整体上属于广搜。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int tar[5][5]={ {0,0,0,0,0}, {0,1,2,3,0}, {0,8,0,4,0}, {0,7,6,5,0}, {0,0,0,0,0} }; const int dx[5]={0,-1,1,0,0}; const int dy[5]={0,0,0,1,-1}; const int mod=100007; struct node { int x,y,eva,id,map[5][5]; bool operator <(const node &a) const { return eva>a.eva; } }; int map[5][5],ans=10000,maxdep,x,y; bool flag=0; void init() { char ch[10]; scanf("%s",ch); int i,k=0,j=1; for (i=0;i<=8;++i) /*先转化为矩阵形式*/ { k++; if (k>3) { k%=3; j++; } map[j][k]=ch[i]-'0'; if (ch[i]=='0') { x=j; y=k; } } } node addnode(int x,int y,int eva,int id,int map[5][5]) { node tmp; tmp.x=x; tmp.y=y; tmp.eva=eva; tmp.id=id; memcpy(tmp.map,map,sizeof(tmp.map)); return tmp; } int evaluate(int map[5][5]) { int res=0; for (int i=1;i<=3;++i) for (int j=1;j<=3;++j) if (map[i][j]!=tar[i][j]) res++; return res; } priority_queue<node> q; void idastar() { int i,j,k,tmp=evaluate(map); while (!q.empty()) q.pop(); q.push(addnode(x,y,tmp,0,map)); while (!q.empty()) { node best=q.top(); q.pop(); if (best.eva==0) { flag=1; break; } int x=best.x,y=best.y; int nowmap[5][5]; memcpy(nowmap,best.map,sizeof(nowmap)); for (i=1;i<=4;++i) { int xx=x+dx[i]; int yy=y+dy[i]; if (xx<1 || xx>3 || yy<1 || yy>3) continue; swap(nowmap[x][y],nowmap[xx][yy]); int noweva=evaluate(nowmap); if (noweva+best.id<ans && noweva+best.id<=maxdep) { q.push(addnode(xx,yy,noweva,best.id+1,nowmap)); } swap(nowmap[x][y],nowmap[xx][yy]); } } } int main() { init(); for (maxdep=0;maxdep<=100;++maxdep) /*限定深度*/ { idastar(); if (flag) { printf("%d",maxdep); break; } } return 0; }
相关文章推荐
- POJ 2513 Colored Sticks 欧拉回路+trie树
- DOM(二)-11-(示例-行颜色间隔显示并高亮)
- Socket通信实例一
- mysql 命令
- 安装numpy和matplotlib简单又不易出错的方法
- 3字节浮点数
- 综合第一篇文章(带钩Quora)
- capturing self strongly in this block is likely to lead to a retain cycle
- Struts2(五)——核心拦截器
- MVC的Views中使用递归生成Html【转】
- 虚拟化--050 vsphere【新提醒】Windows虚拟机10分钟自动同步时间脚本虚拟人工作室 - 虚拟人培训中心
- Go学习笔记
- 动态建立设备节点class_creat/device_creat
- 差分约束系统 & poj 3159 Candies
- 分页的具体实现方法
- 在linux下如何判断是否已经安装某个软件?
- (欧拉回路)uva 10129 Play On Words
- Storm入门教程(二):构建Topology
- 如何快速掌握一门新技术/语言/框架?
- Linux 包管理工具 pip 使用详解