POJ1376(A*)
2016-09-04 16:00
337 查看
题目链接:http://poj.org/problem?id=1376
优先队列默认为大根堆,如果是结构体的比较或者是小根堆的话要自定义cmp函数,但是这里cmp函数和sort里的函数是不一样的,要这样定义:
这里的int替换成结构体也是可以的。
与一般BFS有所不同的是,A*算法要有估价函数f、g、h,把通过现状态 now 所找到的后继状态按照 f 值的大小放入小根堆(open列表)里面去,然后标记now已经遍历过(放入到close列表中)。只是从队列中取出元素的顺序不同而已。
优先队列默认为大根堆,如果是结构体的比较或者是小根堆的话要自定义cmp函数,但是这里cmp函数和sort里的函数是不一样的,要这样定义:
struct cmp { bool operator () (int a, int b) { return a > b; //在sort中返回的是 a < b,正好相反 } }; priority_queue<int, vector<int>, cmp> Q; //小根堆
这里的int替换成结构体也是可以的。
与一般BFS有所不同的是,A*算法要有估价函数f、g、h,把通过现状态 now 所找到的后继状态按照 f 值的大小放入小根堆(open列表)里面去,然后标记now已经遍历过(放入到close列表中)。只是从队列中取出元素的顺序不同而已。
#include <iostream> #include <cstdio> #include <queue> #include <vector> #include <cstring> #include <algorithm> #define INF (1<<31)-1 using namespace std; const int dx[4] = {-1,0,1,0}; //北、东、南、西;上、右、下、左 const int dy[4] = {0,1,0,-1}; const int trn[3] = {-1,1,2}; struct node { int x, y; int f, g, h; int dire; }; node st, ed; int n, m; bool mp[55][55]; int vis[55][55][4]; struct cmp { int operator () (const node& a, const node& b) { if (a.f == b.f) return a.g > b.g; else return a.f > b.f; } }; priority_queue<node,vector<node>,cmp> Q; int Geth(const node& now) //估价函数 { int xx = abs(now.x-ed.x); int yy = abs(now.y-ed.y); int ans = 0; if (xx == 0 && yy == 0) return 0; ans = xx / 3 + yy / 3; if (xx % 3 != 0) ans++; if (yy % 3 != 0) ans++; if (xx != 0 && yy != 0) ans++; if (now.x >= ed.x && now.y <= ed.y) { if (now.dire >= 2) ans++; } if (now.x >= ed.x && now.y >= ed.y) { if (now.dire == 1 || now.dire == 2) ans++; } if (now.x <= ed.x && now.y <= ed.y) { if (now.dire == 0 || now.dire == 3) ans++; } if (now.x <= ed.x && now.y >= ed.y) { if (now.dire <= 1) ans++; } return ans; } int Astar() { while (!Q.empty()) Q.pop(); memset(vis,0,sizeof(vis)); st.f = st.h = Geth(st); st.g = 0; vis[st.x][st.y][st.dire] = true; Q.push(st); while (!Q.empty()) { node now = Q.top(); Q.pop(); if (now.x == ed.x && now.y == ed.y) return now.g; node New; for (int step=1; step<=3;step++) { New.x = now.x+dx[now.dire]*step; New.y = now.y+dy[now.dire]*step; New.dire = now.dire; if (New.x <= 0 || New.x >= n || New.y <= 0 || New.y >= m || mp[New.x][New.y]) break; if (!vis[New.x][New.y][New.dire]) { New.h = Geth(New); New.g = now.g + 1; New.f = New.g + New.h; Q.push(New); vis[New.x][New.y][New.dire] = true; } } for (int i=0; i<2; i++) { New = now; New.dire = (now.dire+trn[i]+4) % 4; if (!vis[New.x][New.y][New.dire]) { New.h = Geth(New); New.g = now.g + 1; New.f = New.g + New.h; Q.push(New); vis[New.x][New.y][New.dire] = true; } } } return -1; } int main() { while (scanf("%d%d",&n,&m)) { if (n == 0 && m == 0) break; memset(mp,0,sizeof(mp)); char str[10]; for (int i=0; i<n; i++) for (int j=0; j<m; j++) { int x; scanf("%d",&x); if (x == 1) mp[i][j] = mp[i][j+1] = mp[i+1][j] = mp[i+1][j+1] = 1; } scanf("%d%d",&st.x,&st.y); scanf("%d%d",&ed.x,&ed.y); scanf("%s",str); switch (str[0]) { case 'n':st.dire = 0; break; case 'e':st.dire = 1; break; case 's':st.dire = 2; break; case 'w':st.dire = 3; break; } cout<<Astar()<<endl; } return 0; }
相关文章推荐
- CSS3:各种浏览器私有属性
- Codeforces Round #359 (Div. 2) B
- Photoshop纹理制作——毛发纹理
- Android工具类--SD卡信息类
- 排序算法集合 - 4
- 第三章 進程管理
- 第二章 從內核出發
- 随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比
- 【JSP笔记】第一章 JAVA WEB简介
- Python日记——nginx+Gunicorn部署你的Flask项目
- 拖动条 SeekBar 实例
- 【牛客网】矩阵中的路径
- MyBatis学习之三:动态SQL语句
- GDB调试程序
- [Lintcode]Container With Most Water
- Android Dialog的 WindowLeaked窗体泄露异常
- spring的事务配置详解
- SVM边学边总结系列——非线性可分情况
- 数组形参2
- 期货交易流程