首页 > 代码库 > 八数码八境界代码
八数码八境界代码
判断无解的情况(写完七种境界才发现有直接判断无解的方法):
一个状态表示成一维的形式,求出除0之外所有数字的逆序数之和,也就是每个数字前面比它大的数字的个数的和,称为这个状态的逆序。
若两个状态的逆序奇偶性相同,则可相互到达,否则不可相互到达。
POJ提交记录(从下往上依次为第1,2,3,4,5,6,7,8境界):
本文转自:http://www.cnblogs.com/zufezzt/p/5659276.html
HDU提交记录(从下往上依次为第1,2,3,4,5,6,7,8境界):
PS:因为HDU是多组测试数据,所以一般POJ上要100ms以上才能AC的方法,在HDU上是无法通过的(境界3除外)。
境界一、 暴力广搜+STL (HDU 内存超限,POJ 时间超限)
map存路径,set判重,string存状态,毫无疑问,炸了。
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<set> #include<map> #include<algorithm> #include<iostream> using namespace std; char input[1000]; int dir[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } }; string d = "durl"; set<string>f; map<string, string>m; int sz = 0; struct node { string s; string path; int pos; node() {} node(string str, string pa, int Pos) { s = str; path = pa; pos = Pos; } }; bool g(int a, int b) { if (a >= 0 && a <= 2 && b >= 0 && b <= 2) return 1; return 0; } void pre() { queue<node>q; q.push(node("12345678x", "", 8)); m["12345678x"] = ""; f.insert("12345678x"); while (!q.empty()) { node h = q.front(); q.pop(); int a = h.pos / 3, b = h.pos % 3; for (int i = 0; i<4; i++) { int x = a + dir[i][0], y = b + dir[i][1]; if (!g(x, y)) continue; int pos = 3 * x + y; swap(h.s[h.pos], h.s[pos]); if (f.find(h.s) != f.end()) { swap(h.s[h.pos], h.s[pos]); continue; } q.push(node(h.s, d[i] + h.path, pos)); f.insert(h.s); m[h.s] = d[i] + h.path; swap(h.s[h.pos], h.s[pos]); } } } int main() { pre(); while(~scanf("%s",input)) { string v=""; v = v + input[0]; for (int i = 1; i <= 8; i++) { scanf("%s", input); v = v + input[0]; } if (m[v] == "") cout << "unsolvable" << endl; else cout << m[v] << endl; } return 0; }
境界二、广搜+哈希(POJ 453ms)
利用康托展开对状态进行hash,hash值对应0--(9!-1),因此可以开数组判重,路径的记录可以记录到达某状态的最后一步操作是什么与父节点是什么。
从输入的状态开始进行BFS,直到找到最终状态。
八数码八境界代码
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。