[数据结构]八数码(暴力,解答树,BFS+hash)
2015-06-22 10:42
585 查看
/* Name:八数码(BFS+hash) Actor:HT Time:2015年6月22日 Error Reporte: 1.memcmp==0 代表匹配成功 2.memcpy(&+数组名,&+数组名,sizeof(数组名)) } */ #include"stdio.h" #include"iostream" #include"string.h" using namespace std; int map[1000000][9]; //看做无限大队列,其中每个元素都具有9个点,也就是说每个元素都是一张图 int goal[9]; int ans[1000000]; //答案,移动的步数,也就是深度,要对应每个元素 const int my[4] = { -1, 0, 1, 0 }; const int mx[4] = { 0, 1, 0, -1 }; //图上移动,这样很方便 分别为上右下左 const int mz[4] = { -3, 1, 3, -1 }; //串上移动 int hashhead[1000000] = { 0 }; //无数个空hash的表头,每个表头用于存储hash值一样的一类“map元素的序号”,下标是个hash值 int hashtable[1000000] = { 0 }; //无数个指向空的hash的指针,每个指针的下标和值都是“map元素的序号”;其实就是一个“序号”组成的链表 int fa[10000000] = { 0 }; //写着玩 void print(int m) //写着玩 { int i; for (i = 0; i < 9; i++) { cout <<map[m][i]<< " "; if (i % 3 == 2) cout << endl; } } int ahash(int rear) { int i,t=0; for (i = 0; i < 9; i++) //hash数值设定,把所有的情况归结到几个hash值中 { t *= 10; t += map[rear][i]; t %= 1000000; } int rearlyhash = hashhead[t]; //找到这个hash数值应该对应的表的表头的真值(某个map元素的元素序号) while (rearlyhash) //沿着这条链表开始搜索 { if (memcmp(map[rearlyhash], map[rear], sizeof(map[rear])) == 0) return 0; rearlyhash = hashtable[rearlyhash]; } hashtable[rear] = hashhead[t]; //这个新来的序号(rear)的下一个指向表头 hashhead[t] = rear; //新来的序号成为了新的表头 return 1; } int bfs() { int zero,x,y; //零点在串的位置,以及在图的坐标 int i; int front = 1, rear = 2; ans[front] = 0; while (front < rear) { if (memcmp(map[front],goal,sizeof(goal)) == 0) return front; for (i = 0; i < 9; i++) if (map[front][i] == 0) { zero = i; break; } //先找到0点 x = zero % 3; //分别为0 1 2 y = zero / 3; //分别为0 1 2 for (i = 0; i < 4; i++) { int newx = x + mx[i], newy = y + my[i], newz= zero + mz[i]; if (newx > 2 || newx < 0 || newy > 2 || newy < 0) continue; memcpy(&map[rear], &map[front], sizeof(map[front])); map[rear][zero] = map[front][newz]; map[rear][newz] = map[front][zero]; //生成新的map,准备放入队列 ans[rear] = ans[front] + 1; fa[rear] = front; //写着玩,印图用 if (ahash(rear)==1) rear++; } front++; } } int main() { int i,sum; for (i = 0; i < 9; i++) cin >> map[1][i]; for (i = 0; i < 9; i++) cin >> goal[i]; sum = bfs(); cout << ans[sum]<<endl; for (i = sum; fa[i] != 0; i = fa[i]) //写着玩 { print(i); cout << "\n\n"; } system("pause"); }
相关文章推荐
- 数据结构学习之二叉树(性质总结)
- HdU5266(LCA + 线段树)
- 每日刷题(2015/6/21):对比哈希表和STL map。哈希表是怎么实现的?如果输入数据规模不大, 可以使用什么数据结构来代替哈希表。
- COJ 0981 WZJ的数据结构(负十九)树综合
- 数据结构——改进的冒泡排序(c++)
- 数据结构——希尔排序(c++)
- 数据结构——直接选择排序(c++)
- 数据结构——直接插入排序(c++)
- 数据结构——二叉树2(c++)
- 词典的实现(3)--使用JAVA类库ArrayList实现Map数据结构
- 数据结构——二叉树1(c++)
- Java数据结构系列——简单排序:泡、选择、直接进入
- 数据结构基础
- 二叉树学习笔记 分类: C/C++ 数据结构与算法 2015-06-21 12:00 36人阅读 评论(0) 收藏
- 数据结构实验之二叉树的建立与遍历
- 数据结构实验之二叉树的建立与遍历 分类: 树 2015-06-21 11:02 8人阅读 评论(0) 收藏
- 数据结构实验之求二叉树后序遍历和层次遍历
- 数据结构实验之求二叉树后序遍历和层次遍历 分类: 树 2015-06-21 10:58 11人阅读 评论(0) 收藏
- [数据结构]八皇后(暴力,解答树,DFS回溯)
- 二叉树的三种遍历方式:递归、栈、循环 分类: C/C++ 数据结构与算法 2015-06-21 09:47 269人阅读 评论(0) 收藏