Enterprising Escape

来源:互联网 发布:java高并发问题 编辑:程序博客网 时间:2024/05/21 18:42

原题链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1815

分析题意可知,这是一道变形的最短路径问题,通过寻找总作战次数最少的路线来求出最终结果

通过广度搜索加上贪心算法的思维来求出答案。其中为了优化搜索时间,使用了优先队列的贪心思维,而不使用优先队列的话,可能面临超时的问题,且会大大增加算法的复杂度。

个人源代码:

#include <iostream>#include <cstdio>#include <queue>using namespace std;int cla_s[26];                                   //记录大写字母对应的战斗次数 char a[1005][1005];                              //记录矩阵 bool visited[1005][1005];                        //标记是否进行过访问 int dire[4][2] = { {-1,0},{1,0},{0,-1},{0,1} }; //四个方向 ,上下左右 int n,m;                                        //矩阵的行数和列数 struct node {int x,y;                                    //节点坐标 long long co;                               //记录着走到当前结点的最少战斗次数 };bool operator<(const node &a,const node &b) {   //运算符重载,便于使用优先队列 return a.co>b.co;}node sta;                                       //开始结点 bool is_band(node a) {                          //判断当前结点是否是边界 if (a.x==1 || a.x==n) return true;if (a.y==1 || a.y==m) return true;return false;}void BFS() {                                      //广度搜索算法函数 node cur,pre;priority_queue<node> q;                      //优先队列,根据重载的运算符进行排序 sta.co=0;visited[sta.x][sta.y]=true;q.push(sta);while (!q.empty()) {pre=q.top();q.pop();if (is_band(pre)) {printf("%lld\n",pre.co); break;}for (int i=0; i<4; i++) {cur.x=pre.x+dire[i][0];cur.y=pre.y+dire[i][1];if (cur.x<1 || cur.x>n || cur.y<1 || cur.y>m) continue; //当前结点越界,跳过 cur.co=pre.co+cla_s[a[cur.x][cur.y]-'A'];               //更行当前的结点战斗次数 if (visited[cur.x][cur.y]) continue;visited[cur.x][cur.y] = true;q.push(cur);}}}int main() {int T;cin>>T;char cls;int tim;char ss[1010];while (T--) {int c;scanf ("%d%d%d",&c,&m,&n);while (c--) {cin>>cls>>tim;cla_s[cls-'A'] = tim;}for (int i=1; i<=n; i++) {scanf ("%s",ss);for (int j=1; j<=m; j++) {a[i][j] = ss[j-1];visited[i][j]=false;if (a[i][j]=='E') {sta.x=i; sta.y=j;}}}BFS();}return 0;}

0 0
原创粉丝点击