1026优先队列

来源:互联网 发布:阿里云和腾讯云比较 编辑:程序博客网 时间:2024/06/05 16:12
#include<stdio.h>
#include<queue>
using namespace std;
int n,m,a[2][4]={{1,0,-1,0},{0,1,0,-1}};

struct node
{
    int i,j,time;
    friend int operator<(node a,node b)
    {
        return a.time>b.time;
    }
};

struct labyrinth
{
    char c;
    int i,j,fight;
}maze[100][100];

int bfs()
{
    priority_queue<node>q;
    node now,next;
    int i;
    now.i=n-1;now.j=m-1;
    if(maze[n-1][m-1].c>'0'&&maze[n-1][m-1].c<='9')
    {
        maze[n-1][m-1].fight=maze[n-1][m-1].c-'0';
        now.time=maze[n-1][m-1].fight;
    }
    else
    {
        maze[n-1][m-1].fight=0;
        now.time=maze[n-1][m-1].fight;
    }
    maze[n-1][m-1].c='X';
    q.push(now);
    while(!q.empty())
    {
        now=q.top();
        q.pop();
        for(i=0;i<4;i++)
        {
            if(now.i+a[0][i]>=0&&now.i+a[0][i]<n&&now.j+a[1][i]>=0&&now.j+a[1][i]<m&&maze[now.i+a[0][i]][now.j+a[1][i]].c!='X')
            {
                maze[now.i+a[0][i]][now.j+a[1][i]].i=now.i;
                maze[now.i+a[0][i]][now.j+a[1][i]].j=now.j;
                next.i=now.i+a[0][i];
                next.j=now.j+a[1][i];
                next.time=now.time+1;
                if(next.i==0&&next.j==0)
                {
                    return next.time;
                }
                if(maze[now.i+a[0][i]][now.j+a[1][i]].c>'0'&&maze[now.i+a[0][i]][now.j+a[1][i]].c<='9')
                {
                    maze[now.i+a[0][i]][now.j+a[1][i]].fight=maze[now.i+a[0][i]][now.j+a[1][i]].c-'0';
                    next.time+=maze[now.i+a[0][i]][now.j+a[1][i]].fight;
                }
                maze[next.i][next.j].c='X';
                q.push(next);
            }
        }
    }
    return 0;
}

int main()
{
    int i,cnt,j,t,s,ii,jj;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        getchar();
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                maze[i][j].fight=0;
                scanf("%c",&maze[i][j].c);
            }
            getchar();
        }
        cnt=bfs();
        if(!cnt)
            printf("God please help our poor hero.\n");
        else
        {
            printf("It takes %d seconds to reach the target position, let me show you the way.\n",cnt);
            for(t=1,i=j=0;t<=cnt;t++)
            {
                printf("%ds:(%d,%d)->(%d,%d)\n",t,i,j,maze[i][j].i,maze[i][j].j);
                ii=maze[i][j].i;
                jj=maze[i][j].j;
                i=ii;j=jj;
                if(maze[i][j].fight>0)
                {
                    for(s=1;s<=maze[i][j].fight;s++)
                    {
                        t++;
                        printf("%ds:FIGHT AT (%d,%d)\n",t,i,j);
                    }
                }
            }
        }
        printf("FINISH\n");
    }
    return 0;
}


其实,想想清楚的话和原来数学题目还是有一定联系的,起码在思维上。

这道题一开始拿到时问题就不在求最短路径,而在于打印每一步,你若认为bfs只是将元素加入队列的话是想不到要去逆向遍历找到路径的关系的,其实我在一开始也想过找路径之间的关系,但光是这一点是不够的,你必须发现正向的遍历面对的问题是最开始的路径是不确定的,即便你找到了关系但实际上你的关系是错位的,这个时候很自然的想到是不是应该到了终点后按照关系反着来一次,把一开始的那几个点重置后在一遍遍历输出,这种代码复杂,而且估计还有别的问题,所以解析很自然的把目光放在了上述三遍的后两遍,我们可以直接反着从终点开始广搜遍历求出终点到起点的最短距离,这样做的好处是第二遍按照关系回来的时候路径是确定不错位的

0 0
原创粉丝点击