题目:http://poj.org/problem?id=2243
A* 算法参考资料:http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10412 | Accepted: 5886 |
Description
Input
Output
Sample Input
e2 e4 a1 b2 b2 c3 a1 h8 a1 h7 h8 a1 b1 c3 f6 f6
Sample Output
To get from e2 to e4 takes 2 knight moves. To get from a1 to b2 takes 4 knight moves. To get from b2 to c3 takes 2 knight moves. To get from a1 to h8 takes 6 knight moves. To get from a1 to h7 takes 5 knight moves. To get from h8 to a1 takes 6 knight moves. To get from b1 to c3 takes 1 knight moves. To get from f6 to f6 takes 0 knight moves.
Source
很裸的 BFS 题目,为了解决HDU上多组数据的八数码问题今天初步学了下 A* 算法,拿来先练手。
code2: A*算法
介绍A*算法的文章中对于这题的 H 有点问题,但是能够 AC 不过过不了大一点的棋盘,因为棋盘稍大的时候如果按照哈曼顿距离求出的未必是最优解
考虑到 G 是由欧几里得距离求的,这里的 H也改成欧几里得距离
对于算法的理解还是不够深刻,多做题了再总结吧Orz
#include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; int vis[10][10]; int dir[8][2] = {1,2, 2,1, 2,-1, 1,-2, -1,-2, -2,-1, -2,1, -1,2}; char start[3], end[3]; int sx,sy,ex,ey; struct Node{ int x,y; int step; int f,g,h;// f = g + h; //G 起点到当前点的费用 //H 当前点到终点的估计费用【此处是欧几里得距离】 Node(){} Node(int _x, int _y, int _step, int _g, int _h) { x = _x; y = _y; step = _step; f = _g + _h; g = _g; h = _h; } //构造优先队列 bool operator <(const Node &a) const { return a.f < f; } }; bool inMap(int x, int y) { if(x <= 0 || x > 8 || y <= 0 || y > 8) return false; return true; } //从(x,y) 到终点的估计费用 【欧几里得距离】 int getH(int x, int y) { double x1 = x, x2 = ex, y1 = y, y2 = ey; //写的有点丑。。。 double dist = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))*10; return (int)dist; } void aStart() { priority_queue<Node> q; while(!q.empty()) q.pop(); Node now ,next; now = Node(sx,sy,0, 0, getH(sx,sy)); memset(vis, 0, sizeof(vis)); vis[sx][sy] = 1; q.push(now); while(!q.empty()) { now = q.top(); q.pop(); for(int i = 0; i < 8; i++) { next.x = now.x + dir[i][0]; next.y = now.y + dir[i][1]; if(!vis[next.x][next.y] && inMap(next.x, next.y)) { vis[next.x][next.y] = 1; next.step = now.step + 1; next.g = now.g + 23; next.h = getH(next.x, next.y); next.f = next.g + next.h; q.push(next); if(next.x == ex && next.y == ey) { printf("To get from %c%c to %c%c takes %d knight moves.\n", start[0], start[1], end[0], end[1], next.step); return; } } } } return; } int main() { while(scanf("%s%s", start, end) != EOF) { sx = start[0] - 'a' + 1; sy = start[1] - '0'; ex = end[0] - 'a' + 1; ey = end[1] - '0'; if(sx == ex && sy == ey) { printf("To get from %c%c to %c%c takes 0 knight moves.\n", start[0], start[1], end[0], end[1]); continue; } aStart(); } return 0; }
code1:裸BFS 代码
//裸 BFS 解法 #include<stdio.h> #include<string.h> #include<queue> using namespace std; int vis[10][10]; int dir[8][2] = {1,2, 2,1, 2,-1, 1,-2, -1,-2, -2,-1, -2,1, -1,2}; char start[3], end[3]; int sx,sy,ex,ey; struct Node{ int x,y; int step; }; bool inMap(int x, int y) { if(x <= 0 || x > 8 || y <= 0 || y > 8) return false; return true; } void bfs() { queue<Node> q; while(!q.empty()) q.pop(); Node now, next; now.x = sx, now.y = sy; now.step = 0; memset(vis, 0, sizeof(vis)); vis[sx][sy] = 1; q.push(now); while(!q.empty()) { now = q.front(); q.pop(); for(int i = 0; i < 8; i++) { next.x = now.x + dir[i][0]; next.y = now.y + dir[i][1]; if(!vis[next.x][next.y] && inMap(next.x, next.y)) { vis[next.x][next.y] = 1; next.step = now.step + 1; q.push(next); if(next.x == ex && next.y == ey) { printf("To get from %c%c to %c%c takes %d knight moves.\n", start[0], start[1], end[0], end[1], next.step); return; } } } } return; } int main() { while(scanf("%s%s", start, end) != EOF) { sx = start[0] - 'a' + 1; sy = start[1] - '0'; ex = end[0] - 'a' + 1; ey = end[1] - '0'; if(sx == ex && sy == ey) { printf("To get from %c%c to %c%c takes 0 knight moves.\n", start[0], start[1], end[0], end[1]); } else bfs(); } return 0; }