hdu5433 BFS

题目大意:
小明因为受到大魔王的诅咒,被困到了一座荒无人烟的山上并无法脱离.这座山很奇怪:
这座山的底面是矩形的,而且矩形的每一小块都有一个特定的坐标(x,y)(x,y)和一个高度HH.
为了逃离这座山,小明必须找到大魔王,并消灭它以消除诅咒.
小明一开始有一个斗志值kk,如果斗志为0则无法与大魔王战斗,也就意味着失败.
小明每一步都能从他现在的位置走到他的(N,E,S,W)(N,E,S,W)四个位置中的一个,会消耗(abs(H_1-H_2))/k(abs(H1H2))/k的体力,然后消耗一点斗志。
大魔王很强大,为了留下尽可能多的体力对付大魔王,小明需要找到一条消耗体力最少的路径.
你能帮助小明算出最少需要消耗的体力吗.
 
 
输入描述
第一行输入一个整数T( 1 \leq T \leq 10 )T(1T10)
接下来有TTTT组数据,每组数据有三个整数n,m,kn,m,k含义如题(1 \leq n,m \leq 50, 0 \leq k \leq 50)(1n,m50,0k50)
接下来有nn行,每行mm个字符,如果是数字则表示(i,j)(i,j)的高度H(0 \leq H \leq 9)H(0H9),'#'表示障碍
最后两行分别输入小明的坐标(x_1,y_1)(x1,y1)和大魔王的坐标(x_2,y_2)(x2,y2),小明和魔王都不在障碍上。
输出描述
每组数据对应输出满足要求的体力(保留两位小数)。
如果无法逃离,则输出"No \ AnswerNo Answer"
输入样例
3
4 4 5
2134
2#23
2#22
2221
1 1
3 3
4 4 7
2134
2#23
2#22
2221
1 1
3 3
4 4 50
2#34
2#23
2#22
2#21
1 1
3 3
输出样例
1.03
0.00
No Answer

ps :刚开始每个点都搜了一遍,但是应该搜多遍,找到一个体力最小的就好了。简单BFS。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <bitset>

using namespace std;
#define MAXN 99999999
int n , m , k;
char Map[55][55];
struct point
{
    int x ,y , k;
    double cost;
    friend bool operator< (point n1 ,point n2)
    {
        return n1.cost > n2.cost;
    }
};

int dir[4][2] = {0 , 1 , 0 , -1 ,  -1 ,0 , 1 , 0};
double visit[55][55][55];
void BFS(int sx ,int sy , int ex , int ey )
{
    queue <point>Q;
    point temp , cur;
    temp.x = sx ;
    temp.y = sy ;
    temp.k = k;
    temp.cost = 0;
    visit[sx][sy][k] = 0;
    Q.push(temp);
    while(!Q.empty())
    {
        temp = Q.front();
        Q.pop();
        if(temp.k <= 0)
        {
            return  ;
        }
        for(int i = 0 ; i < 4 ; i ++)
        {
            cur.x = temp.x + dir[i][0];
            cur.y = temp.y + dir[i][1];
            if(cur.x >= 0 && cur.x < n && cur.y >=0 && cur.y < m)
            {
                if( Map[cur.x][cur.y] != '#')
                {
                    cur.k = temp.k - 1;
                    cur.cost = temp.cost + (abs(Map[temp.x][temp.y] - Map[cur.x][cur.y]))*1.0 / (temp.k*1.0);
                    if(visit[cur.x][cur.y][cur.k] - cur.cost > 0)
                    {
                        Q.push(cur);
                        visit[cur.x][cur.y][cur.k] = cur.cost;
                    }
                }
            }
        }
    }
    return ;
}

int main()
{
    int t;
    scanf("%d" , &t);
    while(t--)
    {
        int sx , sy , ex , ey;
        scanf("%d %d %d" , &n , &m , &k);
        for(int i = 0 ; i < n ; i ++)
            cin >> Map[i];
        scanf("%d %d %d %d" , &sx , &sy , &ex , &ey);
        double ans = -1;
        if(k == 0)
        {
            printf("No Answer\n");
            continue;
        }
        for(int i = 0 ; i <= n ; i ++)
            for(int j = 0 ; j <= m ; j ++)
                for(int l = 0 ; l <= k ; l ++)
                    visit[i][j][l] = MAXN;
        ex--;
        ey--;
        BFS(sx-1 , sy-1 , ex , ey );
        double minn = visit[ex][ey][1];
        for(int i = 1 ; i <= k ; i ++) minn = min(minn , visit[ex][ey][i]);
        if(minn < MAXN) printf("%.2lf\n" , minn);
        else printf("No Answer\n");
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值