标签:这一 建议 cstring 标准 star space abs 简介 展开
简介:一个九宫格中有八个数字,一位空格,每次只能移动相邻的两个格子,现要求把九宫格变为“12345678x”的样子(x代表空格)
Sample Input 2 3 4 1 5 x 7 6 8 Sample Output ullddrurdllurdruldr
这里我们要用到康拓展开,具体介绍如下:
康拓展开并不难,相信各位能看懂,所以我们是把九宫格看成了一个字符串数组来解决;用BFS来寻找转移的方法,但是单纯的BFS容易TLE,那么好,我们这里就用到A*算法,A*算法其实并不难,在这里的BFS基础上我们加一个评估函数h(),h()是怎么评估的呢?是通过当前序列每个数字与标准情况下相比较(这个有点难说明白,建议看看一些迷宫类问题,即每走一步,在这一步到终点观望一下还剩多少距离)
通过使用一个优先队列,能降低时间复杂度。相比盲目的BFS来说,是一个相对比较“智能”的算法,代码如下:
#include<iostream> #include<string> #include<queue> #include<stack> #include<cstring> using namespace std; #define N 9 struct Point { char eight[N]; int position; int g,f; friend bool operator <(const Point& a,const Point& b) { return a.f > b.f; } }startPoint; const int fac[] = {1,1,2,6,24,120,720,5040,40320};//康托序列 const int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; const char option[4]={‘d‘,‘r‘,‘u‘,‘l‘}; bool visited[363000]; int pre[363000]; char op[363000]; stack<char> stk; int cantor(Point p) //康拓展开 { int ans=0; for(int i=0 ;i<N ;i++) { int cnt = 0; for(int k=i+1 ;k<N ;k++) if(p.eight[k]>p.eight[i]) cnt++; ans += fac[8-i]*cnt; } return ans; } int ABS(int x){return x<0? -x:x;} //自定义绝对值 int h(Point p) //评估函数 { int val=0; for(int i=0 ;i<N ;i++) { if(p.eight[i]==‘x‘) continue; int c = p.eight[i]-‘1‘; val += ABS(c/3-i/3)+ABS(c%3-i%3); } return val; } bool bfs() { int row,col,cantorValue; memset(visited,false,sizeof(visited)); priority_queue<Point> que; que.push(startPoint); while(!que.empty()) { Point p = que.top(); que.pop(); for(int i=0;i<4 ;i++) { row = p.position/3 +dir[i][0]; col = p.position%3 +dir[i][1]; if(row<0||col<0||row>=3||col>=3) continue; Point newPoint(p); newPoint.eight[newPoint.position] = newPoint.eight[col+row*3]; newPoint.position = col+row*3; newPoint.eight[newPoint.position] = ‘x‘; cantorValue = cantor(newPoint); if(visited[cantorValue]) continue; visited[cantorValue] = true; newPoint.g++; newPoint.f = newPoint.g +h(newPoint); pre[cantorValue] = cantor(p); op[cantorValue] = option[i]; if(cantorValue==0) return true; que.push(newPoint); } } return false; } bool inversionNumberCheck() { int cnt =0; for(int i=0 ;i<N ;i++) { if(startPoint.eight[i]==‘x‘) continue; for(int k=i+1;k<N ;k++) { if(startPoint.eight[k]==‘x‘) continue; if(startPoint.eight[k]<startPoint.eight[i]) cnt++; } } return cnt&1; } int main() { while(cin >> startPoint.eight[0]) { if(startPoint.eight[0]==‘x‘) startPoint.position=0; for(int i=1 ;i<9 ;i++) { cin >> startPoint.eight[i]; if(startPoint.eight[i]==‘x‘) startPoint.position=i; //记录x所在的位置 } if(inversionNumberCheck()) { cout <<"unsolvable" <<endl; continue; } startPoint.g=0; startPoint.f = h(startPoint); int startCantor = cantor(startPoint); bfs(); int index =0; while(index!=startCantor) { stk.push(op[index]); index = pre[index]; } while(!stk.empty()) { cout << stk.top(); stk.pop(); } cout << endl; } }
标签:这一 建议 cstring 标准 star space abs 简介 展开
原文地址:https://www.cnblogs.com/yegowxx23/p/13599493.html