链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=649

题意:有N行,M列的格子,从”r”出发,要到达“a”处,”#”不能走,走”x"要多用一个单位时间,“."用正常的单位时间。求最短时间。

思路:由于要求的是最短的时间,所以用广搜,但是最一般的广搜求出来的是最少的步数,此题要求的是最少的时间。在这个问题中,最少的步数并不代表时间也是最少的,因为可能会有很多的”x“出现,这样时间就长了。用一个结构体来表示当前位置的状态,包括走过的步数和所用的时间。数组mintime[x][y]表示走到(x,y)所花的最少时间,在搜索过程中,从当前位置到相邻的位置(x,y)时,只有当现在这种走法比以前的走法用的时间少,才把当前走到(x,y)位置所表示的状态入队。还有就是必须要等队列空了搜索过程才算结束,因为如果到了目的地搜索就结束的话,得到的是最少步数中的最短时间,并不一定是所求的解。因为入队时是只有当当前走法所花时间更少时才入队,而这个时间有下界,所以不会无限搜索下去。

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

const int maxn=202;
const int INF=1000000;
int dir[4][2]= {{-1,0},{0,1},{1,0},{0,-1}};
struct point
{
    int x,y;
    int step;
    int time;
};
queue<point> q;
int N,M;
char map[maxn][maxn];
int mintime[maxn][maxn];
int ax,ay;

void bfs(point p)
{
    q.push(p);
    point hd;
    while(!q.empty())
    {
        hd=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            int x=hd.x+dir[i][0],y=hd.y+dir[i][1];
            if(x<0 || y<0 || x>=N || y>=M) continue;
            if(map[x][y]=='#') continue;
                point t;
                t.x=x;
                t.y=y;
                t.step=hd.step+1;
                t.time=hd.time+1;
                if(map[x][y]=='x') t.time++;
                if(t.time<mintime[x][y])
                {
                    mintime[x][y]=t.time;
                    q.push(t);
                }
        }
    }
}

int main()
{
    int sx,sy;
    point start;
    while(~scanf("%d%d",&N,&M))
    {
        getchar();
        for(int i=0;i<N;++i)
        {
            for(int j=0;j<M;++j)
            {
                scanf("%c",&map[i][j]);
                mintime[i][j]=INF;
                if(map[i][j]=='a')
                {
                    ax=i;
                    ay=j;
                }
                else if(map[i][j]=='r')
                {
                    sx=i;
                    sy=j;
                }
            }
            getchar();
        }
        start.x=sx;
        start.y=sy;
        start.step=0;
        start.time=0;
        mintime[sx][sy]=0;
        bfs(start);
        if(mintime[ax][ay]<INF) printf("%d\n",mintime[ax][ay]);
        else printf("Poor ANGEL has to stay in the prison all his life.\n");
    }
    return 0;
}

写完代码后就运行,把网上的输入复制了过来,结果一输入就异常退出,以为是代码有问题,检查了好久,还是没发现问题。然后把代码一段的一段的改得和书上的一样,才发现是输入有问题,用书上的写法就是对的,但是明明这么写也是可以的,非常奇怪。于是干脆交了,发现过了,深感郁闷。然后把那个输入复制到文本文件中观察了下,发现每行后面多复制了一个空格。。。。泪,内伤啊。

所以保险起见,以后还是按书上的那样写吧。

while()循环中

        for(int i=0;i<N;i++)
            scanf("%s",map[i]);
        for(int i=0;i<N;++i)
        {
            for(int j=0;j<M;++j)
            {
                mintime[i][j]=INF;
                if(map[i][j]=='a')
                {
                    ax=i;
                    ay=j;
                }
                else if(map[i][j]=='r')
                {
                    sx=i;
                    sy=j;
                }
            }
        }

总之,不爽不爽不爽。

 

 posted on 2013-05-15 19:24  ∑求和  阅读(153)  评论(0)    收藏  举报