HDOJ 1026 Ignatius and the Princess I 搜尋最短路徑

來源:互聯網
上載者:User

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1026

最短很好解決,設定兩個全域變數就可以搞定,每次到達出口時比較所用時間,但是記錄最短路徑比較複雜,目前還沒有實現。題目中涉及到的邊界剪枝,障礙剪枝

就不多說了,還是深度優先,先上代碼,下次有時間再最佳化:

#include <iostream>#include <string>#include <cstdio>#include <cmath>#include <vector>#include <algorithm>#include <sstream>#include <cstdlib>#include <fstream>#include <utility>using namespace std;char map[110][110];vector<pair<int,int> > path;void dfs(int sx,int sy,int endx,int endy);int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};   //上下左右四個方向 int tsum,tmin;int n,m,flag;int main(){//ifstream fin;//fin.open("abc.txt");//cout<<fin.is_open()<<endl;while(cin>>n>>m){tsum=0;flag=0;tmin=999999;            //用來儲存最短的時間,每次都要複製,不然多組測試資料                        //時,始終儲存的最短的一組測試結果 for(int i=0;i<n;i++)for(int j=0;j<m;j++)cin>>map[i][j];dfs(0,0,n-1,m-1);if(flag)cout<<tmin<<endl;else cout<<"God please help our poor hero."<<endl;}//fin.close();return 0;}void dfs(int sx,int sy,int endx,int endy){if(sx==endx&&sy==endy){if(tsum<tmin)tmin=tsum;flag=1;                 //標記是否能到達出口 return ;}for(int i=0;i<4;i++){if(sx+dir[i][0]<0||sx+dir[i][0]>=n||sy+dir[i][1]<0||sy+dir[i][1]>=m)continue;//以上是邊界剪枝 if(map[sx+dir[i][0]][sy+dir[i][1]]=='.'){tsum++;map[sx+dir[i][0]][sy+dir[i][1]]='X';dfs(sx+dir[i][0],sy+dir[i][1],endx,endy);    map[sx+dir[i][0]][sy+dir[i][1]]='.';    tsum--;}else if(map[sx+dir[i][0]][sy+dir[i][1]]>='1'&&map[sx+dir[i][0]][sy+dir[i][1]]<='9'){tsum+=map[sx+dir[i][0]][sy+dir[i][1]]-'0';tsum++;int tmp=map[sx+dir[i][0]][sy+dir[i][1]]-'0'; map[sx+dir[i][0]][sy+dir[i][1]]='X';dfs(sx+dir[i][0],sy+dir[i][1],endx,endy);   map[sx+dir[i][0]][sy+dir[i][1]]=tmp+'0';   tsum-=tmp;   tsum--;}}} 

今天在網上看了一個牛人寫的完整演算法,果然記錄路徑是最複雜的,而且才用了廣度優先搜尋,這裡暫不說為什麼不用深搜來記錄路徑,好吧先把代碼貼上來學習下再說:

轉自:http://www.wutianqi.com/?p=2354

#include <iostream>#include <queue>#include <stack>using namespace std; typedef struct Node{int x, y, cost;      //cost即為到達每一步所用最短時間,注意是最短的 int prex, prey;      //prex,prey,回溯法時記錄前一個位置的變數 }Node; int N, M;char maze[105][105];   // 記錄初始輸入Node path[105][105];   // 記錄路徑int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 判斷(x, y)是否可行bool isOK(int x, int y){if(x>=0 && x<N && y>=0 && y<M && maze[x][y]!='X')return 1;elsereturn 0;} void Init(){    int i, j;    for(i = 0; i < N; ++i)        for(j = 0; j < M; ++j)            path[i][j].cost = -1;} void backPath(int x, int y)    //用來輸出路徑 {    stack<Node> S;Node a, b;    int cc = 1, tmp;     cout << "It takes " << path[N - 1][M - 1].cost << " seconds to reach the target position, let me show you the way." << endl;    a = path[N - 1][M - 1];    while(1)    {        if(a.x == 0 && a.y == 0)            break;        S.push(a);        a = path[a.prex][a.prey];     }                //使用棧來儲存路徑,從出口開始回溯      a = path[0][0];     while(!S.empty())    {        b = S.top();        S.pop();        if(maze[b.x][b.y] == '.')            cout << cc++ << "s:(" << a.x << "," << a.y << ")->(" << b.x << "," << b.y << ")" << endl;        else        {            cout << cc++ << "s:(" << a.x << "," << a.y << ")->(" << b.x << "," << b.y << ")" << endl;            tmp = maze[b.x][b.y] - '0';            while(tmp--)                cout << cc++ << "s:FIGHT AT (" << b.x << "," << b.y << ")" <<endl;        }        a = b;    }    cout<<"FINISH"<<endl;}  int BFS(int x, int y){queue<Node> Q;Node a, b;a.x = a.y = a.cost = a.prex = a.prey = 0;if(maze[0][0] != '.')a.cost = maze[0][0] - '0';path[0][0] = a;Q.push(a); while(!Q.empty()){a = Q.front();Q.pop();for(int i=0; i<4; ++i) //廣度優先搜尋,對於每個點的上下左右四個位置上的點依次處理 {b.x = a.x + dir[i][0];b.y = a.y + dir[i][1];if(!isOK(b.x, b.y))continue;if(maze[b.x][b.y] == '.')b.cost = a.cost + 1;elseb.cost = a.cost + maze[b.x][b.y]-'0' + 1;if(b.cost < path[b.x][b.y].cost || path[b.x][b.y].cost == -1)            {                        //更新每個位置的最短時間                 b.prex = a.x; b.prey = a.y;                path[b.x][b.y] = b;                Q.push(b);            }}}    if(path[N - 1][M - 1].cost == -1)    {        cout << "God please help our poor hero." << endl;        cout << "FINISH" << endl;        return 0;    }backPath(N-1, M-1);}  int main(){while(cin >> N >> M){memset(maze, 0, sizeof(maze));for(int i=0; i<N; ++i)for(int j=0; j<M; ++j)cin >> maze[i][j];Init();BFS(0, 0);}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.