标签:
有关八数码问题及其参考:
http://wenku.baidu.com/view/87c92ef1ba0d4a7302763a29.html
http://blog.csdn.net/damotiansheng/article/details/40017107
http://blog.csdn.net/wsywl/article/details/5726617
下面的代码实现可以在poj上验证其正确性,估价函数可以进行修改.
poj 原题网址:http://bailian.openjudge.cn/practice/1077
1 #include <iostream> 2 #include <map> 3 #include <algorithm> 4 #include <string> 5 #include <queue> 6 #include <set> 7 using namespace std; 8 typedef long long LL; 9 10 int eight[3][3], xx, xy, dx[]={0,-1,1,0}, dy[]={1,0,0,-1}; 11 char dir[] = "rudl"; 12 LL init, tar; 13 14 LL encode(){ 15 LL s=eight[2][2]; 16 for(int i=7; i>=0; --i){ 17 s <<=4; 18 s |= eight[i/3][i%3]; 19 } 20 return s; 21 } 22 void decode(LL s){ 23 for(int i=0; i<9; ++i){ 24 eight[i/3][i%3] = s%16; 25 if(s%16 == 0) 26 xx = i/3, xy = i%3; 27 s >>=4; 28 } 29 } 30 class Node { 31 public: 32 LL s, ps; 33 int f,g,h,d; 34 Node (LL _s=0, LL _ps=0, int _d=-1, int _f=0, int _g=0, int _h=0){ 35 s = _s, ps = _ps, f = _f, g = _g, h = _h, d = _d; 36 } 37 }; 38 class cmp_s{ 39 public: 40 int operator()(const Node &a, const Node &b){ 41 return a.s < b.s; 42 } 43 }; 44 class cmp_f{ 45 public: 46 int operator()(const Node &a, const Node &b){ 47 // 最小堆按大于比较 48 return a.f > b.f || (a.f==b.f && a.s > b.s); 49 } 50 }; 51 set<Node, cmp_s> closed, open; 52 set<Node, cmp_s>::iterator ito, itc; 53 priority_queue<Node, vector<Node>, cmp_f> que; 54 55 void print(Node nd){ 56 int d = nd.d; 57 string ope; 58 while(d!=-1){ 59 ope.push_back(dir[d]); 60 nd.s = nd.ps; 61 itc = closed.find(nd); 62 nd = *itc; 63 d = nd.d; 64 } 65 reverse(ope.begin(), ope.end()); 66 cout<< ope<< "\n"; 67 } 68 int hn(LL s){ 69 decode(s); 70 int cnt=0; 71 for(int i=0; i<9; ++i){ 72 if(eight[i/3][i%3] != (i+1)%9) cnt++; 73 } 74 return cnt; 75 } 76 void astar(){ 77 init = encode(); 78 int inith = hn(init); 79 Node start = Node(init, 0, -1, inith, 0, inith); 80 open.insert(start); que.push(start); 81 while(!open.empty()){ 82 Node tn = que.top(); que.pop(); open.erase(tn); 83 LL ts = tn.s, s2; 84 int tf = tn.f, tg = tn.g, th = tn.h; 85 for(int i=0; i<4; ++i){ 86 decode(ts); 87 int r = xx+dx[i], c=xy+dy[i]; 88 if(r<0 || c<0 || r==3 || c==3) continue; 89 swap(eight[r][c], eight[xx][xy]); 90 s2 = encode(); 91 int g = tg+1, h = hn(s2), f = g+h; 92 Node nd = Node(s2, ts, i, f, g, h); 93 if(s2 == tar){ 94 closed.insert(tn); 95 print(nd); 96 return; 97 } 98 ito = open.find(nd), itc = closed.find(nd); 99 if(ito == open.end() && itc == closed.end()){ 100 open.insert(nd); que.push(nd); 101 } 102 else if(ito == open.end() && f < itc->f){ 103 closed.erase(itc); open.insert(nd); que.push(nd); 104 } 105 else if(itc == closed.end() && f < ito->f){ 106 // que 里有相同s不同f的node 107 open.erase(ito), open.insert(nd), que.push(nd); 108 } 109 } 110 closed.insert(tn); 111 } 112 } 113 int main(){ 114 std::ios::sync_with_stdio(false); 115 char c; 116 for(int i=0; i<3; ++i){ 117 for(int j=0; j<3; ++j){ 118 cin>>c; 119 if(c==‘x‘) 120 eight[i][j]=0, xx = i, xy = j; 121 else 122 eight[i][j]= c-‘0‘; 123 } 124 } 125 tar=8; 126 for(int i=7; i>0; --i) 127 tar<<=4, tar |= i; 128 int cnt=0; 129 for(int i=0; i<9; ++i){ 130 for(int pi=0; pi<i; ++pi) 131 if(eight[pi/3][pi%3] && eight[pi/3][pi%3]<eight[i/3][i%3]) 132 cnt++; 133 } 134 if(cnt%2) 135 printf("unsolvable\n"); 136 else 137 astar(); 138 return 0; 139 }
另外八数码问题的三种实现(bfs,dbfs,a*):
http://www.cnblogs.com/yyf2016/p/5790127.html
标签:
原文地址:http://www.cnblogs.com/yyf2016/p/5792360.html