参考博客:http://blog.csdn.net/ice_crazy/article/details/7763302

我的初学探索:

选择广搜:要求出最短时间。广搜的好处是(树)一层一层的向下进行(将一个结点的所有子结点加入一个先进先出的队列中),找到目标就可终止搜索。

选择优先队列:还是要求出最短时间。将所有可能结点加入队列后,我们希望每次弹出的都是用时最短的,这个最短不是路径最短(结点个数),而是因为需要打怪需要在某个结点停留一段时间。另外,优先队列需要自定义排序。

注意问题:1、走过的路要设为不可走的标记‘X’,不要忘了开始的位置。2、行至某个结点所用时间time用作优先队列的自定义排序。

打印路径:用dir表示4个方向,用flag作为路径的标记。flag[x][y]的值为走到(x,y)位置上的第i个方向(dir[i][]),每个位置至多走一次,所以它不存在覆盖,且可能走过的(包括不是最优的)都会有值,且在[0][0]的位置上值为0(初始值)。然后利用递归从终点向出发点找出路径,直到[0][0],即flag的值为初始值。由于方向dir的下标是从0开始的(flag的值也就包含了0),而我们把flag的初值设为了0,就会引发冲突,所以,对flag赋值时加1,使用时再减去1。

其它:1、fight表示打斗时间。2、细节上,一开始用map直接存打斗时间或0表示可走或-1表示不可走将会更好。

#include <iostream>
#include <queue>
using namespace std;

int m, n;
char map[102][102];
int dir[4][2]={1,0, 0,1, -1,0, 0,-1};
int flag[102][102];
int fight[102][102];  
int totTime;

struct Node{
    int x;
    int y;
    int time;
    bool operator<(const Node &a) const {
        return a.time<time;
    }
};
bool bfs()
{
    priority_queue<Node>que; 
    struct Node start;
    start.x=start.y=start.time=0;
    que.push(start);
    map[0][0]='X';

    while (!que.empty())
    {
        struct Node cur=que.top();
        que.pop();
        if(cur.x==n-1 && cur.y==m-1){
            totTime=cur.time;
            return true;
        }
        for (int i=0; i<4; i++){
            int xtmp=cur.x+dir[i][0];
            int ytmp=cur.y+dir[i][1];
            if(map[xtmp][ytmp]=='X') continue;
            if(xtmp<n && xtmp>=0 && ytmp<m && ytmp>=0 ){
                struct Node nextstep;
                nextstep.x=xtmp;
                nextstep.y=ytmp;
                if(map[nextstep.x][nextstep.y]!='.') {
                    nextstep.time=cur.time+1+map[nextstep.x][nextstep.y]-'0';
                    fight[nextstep.x][nextstep.y]=map[nextstep.x][nextstep.y]-'0';  
                } else
                    nextstep.time=cur.time+1;
                flag[nextstep.x][nextstep.y]=i+1;
                que.push(nextstep);
                map[xtmp][ytmp]='X';
            }
        }
    }
    return false;//没有到达,则返回false
}

int seconds;
void printRoad(int x, int y)
{
    if(flag[x][y]==0) return ;
    int pre_x, pre_y;
    pre_x=x-dir[flag[x][y]-1][0];
    pre_y=y-dir[flag[x][y]-1][1];
    printRoad(pre_x, pre_y);
    printf("%ds:(%d,%d)->(%d,%d)\n",seconds++,pre_x,pre_y,x,y); 
    while(fight[x][y]--)
        printf("%ds:FIGHT AT (%d,%d)\n",seconds++,x,y); 
    
}
int main(){ 
//    freopen("D:/Documents/work/in.txt", "r", stdin);
//    freopen("D:/Documents/work/out.txt",  "w", stdout);
    int i, j;
    while(~scanf("%d%d", &n, &m))
    {
        memset(fight,0,sizeof(fight));
        memset(flag,0,sizeof(flag));
        for(i=0; i<n; i++)
            for(j=0; j<m; j++)
                cin>>map[i][j];
        if(bfs()){
            seconds=1;
             printf("It takes %d seconds to reach the target position, let me show you the way.\n",totTime);
            printRoad(n-1,m-1);
        } else {
            printf("God please help our poor hero.\n");
        }
        printf("FINISH\n"); 
    }

    return 0;
}

 

 posted on 2014-09-20 16:16  平和之心  阅读(966)  评论(0编辑  收藏  举报