codevs 1225_八数码难题_bfs+hash
2017-05-21 15:56
411 查看
题目描述
Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
思路
显然一共有9!种情况,而且这个数不是很大所以我们可以直接打一个单向bfs
将每一种状态都看成是一个字符串,那么我们在找到’0’的位置后按常理来说可以往”上,下,左,右”四个方向进行交换,那么很容易看出如果将这个3*3的矩形转换为了一个字符串后,这四个方向分别对应的变换位置就是{-3,3,-1,1},那么这样的话就可以很容易的用字符串表示当前的状态并进行转化
打广搜的话,很明显要记忆化,不然那么多种状态,那么多重复,不爆队列就怪了
用了map进行判重(毕竟好写)
然而map会超时,所以改用hash
#include <stdio.h> #include <string> #include <cstring> #include <map> #include <iostream> #include <queue> #include <cstdlib> using namespace std; #define p 10000007 string start, ed="123804765"; int h[p+1]; int dx[5]={0,1,-1,3,-3}; int fl=0; int insert(int x) { int i=x%p; while (h[i]!=0) i=(i+1)%p; h[i]=x; } int find(int x) { int i=x%p; while (h[i]!=0&&h[i]!=x) i=(i+1)%p; if (h[i]==x) return 1; return 0; } int bfs() { queue<string> t; queue<int> state; t.push(start); state.push(0); int xx=std::atoi(start.c_str()); insert(xx); while (!t.empty()) { string now = t.front(); int ns = state.front(); t.pop(); state.pop(); int l = now.find('0'); for (int i = 1; i <= 4; i++) { if (l + dx[i] < 0 || l + dx[i] > 8) continue; if ((l == 3 && dx[i] == -1)||(l == 6 && dx[i] == -1)) continue; if ((l == 2 && dx[i] == 1)||(l == 5 && dx[i] == 1)) continue; string ne = now, ch = now.substr(l + dx[i], 1); ne.replace(l, 1, ch); ch = '0'; ne.replace(l+dx[i], 1, ch); int xx=std::atoi(ne.c_str()); if (!find(xx)) { insert(xx); t.push(ne); state.push(ns + 1); if (ne == ed) { fl = 1; printf("%d\n", ns + 1); return 0; } } } } } int main() { for (int i = 1; i <= 9; i++) { char ch = getchar(); while (ch < '0' || ch > '8') {ch = getchar();} start += ch; } bfs(); if (fl == 0) printf("-1"); }
相关文章推荐
- CODEVS 1225 八数码难题(BFS && A*)
- codevs 1225 八数码难题 搜索+Hash 解题报告
- 【Codevs1225】 八数码难题 BFS (1/1000)
- 八数码难题 双向搜索(codevs 1225)
- 【codevs1225】八数码难题,如何精确地搜索
- Codevs 1225 八数码难题
- Codevs 1225 八数码难题
- codevs1225 八数码难题 bfs+哈希
- codevs1225 八数码难题(A*搜索+康托展开)
- 八数码难题 (codevs 1225)题解
- [codevs1225]八数码难题
- CODE[VS] 1225 八数码难题
- Codevs1225 八数码难题
- 【基础练习】【BFS+A*】codevs1225八数码难题题解
- codevs1225 八数码难题(A*搜索+康托展开)
- 【CodeVS1225】八数码难题
- codevs1225 八数码难题
- codevs1225八数码难题(搜索·)
- codevs 1004 四子连棋 BFS、hash判重
- 八数码难题 codevs1225 a*