HNUST 1454: 挑战ACM迷宫(BFS+贪心)

来源:互联网 发布:java打印直角三角形 编辑:程序博客网 时间:2024/06/11 09:10

1454: 挑战ACM迷宫

时间限制: 1 Sec  内存限制: 128 MB
提交: 534  解决: 122
[提交][状态][讨论版]

题目描述

如下图所示的是一个由程序设计题目组成的ACM迷宫。迷宫的左上角是入口,右下角是出口。迷宫中每一个格子都有一个程序设计题目,挑战者要AC该题目后才能通过,大于0的数字表示AC该题目所需的最短时间。数字如果是0表示是陷阱,进去了就出不来。现在的问题是:求挑战者从入口到出口所需的最短时间。

输入

有多组测试实例。

对于每组测试实例,先输入一个数字n(1<n<=100),然后输入n*n个数字表示迷宫中的数字。

输出

对应输出挑战者从入口到出口所需的最短时间。

    闲来无事重新回顾了下老内容,本题题意很清晰,显然搜索,DFS我试过,超时(应该是我太菜了剪枝不行)。直接BFS显然不能使路径最短,所以加上贪心·,每走一步都判断上下左右(如果有四个方向)哪一个方向上距离最短,最短的就将值保存。

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#define LL long longusing namespace std;int mini;int vis[102][102],map[102][102];int n;int dirs[4][2]={0,1,0,-1,1,0,-1,0};struct person{    int hang,lie,zhi;  ///结构体咯,zhi是保存到当前路径的最短长度} start,t,zhong;int in(int a,int b)  ///在范围内,我的下标是从一到n的{    if(a>=1&&a<=n&&b>=1&&b<=n)        return 1;    else        return 0;}void  BFS(){    queue <person> que;   ///这儿有个细节,如果把队列定义在这里,那就不用每次完了清空队列。    que.push(start);    while(!que.empty())    {        t = que.front();        que.pop();        for(int i=0; i<4; i++)        {            zhong.hang = t.hang + dirs[i][0];            zhong.lie = t.lie+ dirs[i][1];            if(in(zhong.hang,zhong.lie)&& map[zhong.hang][zhong.lie])                if(t.zhi + map[zhong.hang][zhong.lie] < vis[zhong.hang][zhong.lie])  ///循环打擂,选最小                {                    vis[zhong.hang][zhong.lie] = t.zhi + map[zhong.hang][zhong.lie];                    zhong.zhi=vis[zhong.hang][zhong.lie];                    que.push(zhong);                }        }    }}int main(){    while(scanf("%d",&n)==1)    {        for(int i=0; i<=n; i++)            for(int j=0; j<=n; j++)                vis[i][j]=1000000;   ///赋初值,使它尽可能大。                                      ///注意的是我的vis数组不是标记位,是到当前位的最短距离        for(int i=1; i<=n; i++)            for(int j=1; j<=n; j++)                scanf("%d",&map[i][j]);        start.hang=1;        start.lie=1;        start.zhi=map[1][1];        BFS();        printf("min=%d\n",vis[n][n]);    }    return 0;}