DLUTOJ 1147: 翼神的跑毒之旅(bfs)

1147: 翼神的跑毒之旅
Time Limit:4000/2000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)
Total Submissions:43 Accepted:7
[Submit][Status][Discuss]
Description
翼神沉迷吃鸡,但他的技术和人品只能让他不断跑毒。

给定n∗n的格点表示游戏地图,安全区则由一片标记为’X’的联通区域构成,翼神从标记为’S’的点出发,只有在k秒内跑进安全区就可以活下去。

一般情况下,翼神需要花费2秒时间只向左、向右、向上或向下走过1个格点,但地图上标记为’C’的点有车(保证车的数量≤100),翼神驾车时只需花费1秒钟就能通过1个格点。

当然问题并没有简单,地图上只有标记为’.’的点可以通过(当然标记为’X’,’S’与标记为’C’的区域也同样可以通过),而标记为’O’的点则是翼神无法穿过的悬崖和陡坡。

请问翼神能否活下去?如果能活下去,翼神抵达安全区的最快时间是多少?
Input有t组样例t≤10,每组样例包含两个整数n,k,1≤n≤100,k≤109
接下来包含一张n∗n的地图。
Output
首先判断翼神是否能够存活,如果不能,输出“NO”,如果可以存活,输出”YES”并输出翼神抵达安全区的最快时间。
Sample Input
3
2 3
.X
S.
2 3
.X
SC
2 4
.X
S.
Sample Output
NO
YES
3
YES

4


题解:由于图的规模是100*100,所以无法进行dfs,但是我们可以采用bfs(由于是无权图),比dfs快的多。先从起点S开始,进行bfs对经过的C位置进行记录,同时使用shortes[maxn][maxn]数组,记录任意点到S的最短路,这样会得到完全步行的最短时间,之后在对每一处记录的车的位置进行bfs,对所有答案取最小值,这样就是最优解,与K进行比较即可。


代码:

#include<iostream>
#include<fstream>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
#include<utility>
#include<algorithm>
#include<map>
#include<stack>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 105;
const int mod = 1e9+7;
const int INF = 1<<30;
const ll llINF = 1e18+999;

int k, n, T, isvisited[maxn][maxn], shortest[maxn][maxn], ans;
struct node
{
    int xx, yy;
    node(int a, int b)
    {
        xx = a;
        yy = b;
    }
};
queue<node> car;
char arr[maxn][maxn];
void bfs(int x, int y, int speed)
{
    memset(isvisited, 0, sizeof(isvisited));
    isvisited[x][y] = 1;
    queue<node> q;
    q.push(node(x, y));
    while(!q.empty())
    {
        node node1 = q.front( );
        q.pop( );
        x = node1.xx;
        y = node1.yy;
        if(arr[x][y] == 'X')
        {
            ans = min(ans, shortest[x][y]);
            return;
        }
        if(arr[x][y] == 'C' && speed==2)
            car.push(node(x, y));
        if(x-1>-1 && arr[x-1][y]!='O' && !isvisited[x-1][y])
        {
            isvisited[x-1][y] = 1;
            shortest[x-1][y] = shortest[x][y]+speed;
            q.push(node(x-1, y));
        }
        if(x+1<n && arr[x+1][y]!='O' && !isvisited[x+1][y])
        {
            isvisited[x+1][y] = 1;
            shortest[x+1][y] = shortest[x][y] + speed;
            q.push(node(x+1, y));
        }
        if(y-1>-1 && arr[x][y-1]!='O' && !isvisited[x][y-1])
        {
            isvisited[x][y-1] = 1;
            shortest[x][y-1] = shortest[x][y] + speed;
            q.push(node(x, y-1));
        }
        if(y+1<n && arr[x][y+1]!='O' && !isvisited[x][y+1])
        {
            isvisited[x][y+1] = 1;
            shortest[x][y+1] = shortest[x][y] + speed;
            q.push(node(x, y+1));
        }
    }
}
int main( )
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    scanf("%d", &T);
    while(T--)
    {
        memset(shortest, 0, sizeof(shortest));
        while(!car.empty())
            car.pop();
        ans = INF;
        scanf("%d%d", &n, &k);
        for(int i=0; i<n; i++)
            scanf("%s", arr[i]);
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                if(arr[i][j] == 'S')
                    bfs(i, j, 2);
        while(!car.empty())
        {
            node node1 = car.front( );
            car.pop();
            bfs(node1.xx, node1.yy, 1);
        }
        if(ans > k)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl<<ans<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值