Xiao Ming climbing


Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1227    Accepted Submission(s): 344



Problem Description


Due to the curse made by the devil,Xiao Ming is stranded on a mountain and can hardly escape.

This mountain is pretty strange that its underside is a rectangle which size is  n∗m and every little part has a special coordinate (x,y)and a height  H.

In order to escape from this mountain,Ming needs to find out the devil and beat it to clean up the curse.

At the biginning Xiao Ming has a fighting will  k,if it turned to  0 Xiao Ming won't be able to fight with the devil,that means failure.

Ming can go to next position (N,E,S,W)from his current position that time every step, (abs(H1−H2))/k 's physical power is spent,and then it cost  1 point of will.

Because of the devil's strong,Ming has to find a way cost least physical power to defeat the devil.

Can you help Xiao Ming to calculate the least physical power he need to consume.


 



Input


T(T≤10), indicating the number of testcases. 

Then  T testcases follow.

The first line contains three integers  n,m,k ,meaning as in the title (1≤n,m≤50,0≤k≤50).

Then the  N ×  M matrix follows.

In matrix , the integer  H meaning the height of  (i,j),and '#' meaning barrier (Xiao Ming can't come to this) .

Then follow two lines,meaning Xiao Ming's coordinate (x1,y1) and the devil's coordinate (x2,y2),coordinates is not a barrier.


 



Output


NoAnswer" otherwise.

(The result should be rounded to 2 decimal places)


 



Sample Input


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


 



Sample Output


1.03 0.00 No Answer


 



Source


BestCoder Round #55 ($)


 


这个题真是快折磨死自己了,各种WA。


一道迷宫题目:


只让你走k步,每一步都消耗abs(h1-h2)/k的体力,问能否从起点到达终点,并且消耗体力最少!



思路:


BFS可以用dp[x][y][k]来表示状态。表示走到x,y这个点时,还有k步可走时,的体力消耗总值。


建立一个结构体包含,int x,y,k doulbe will,   这里will记录体力消耗总值。


构建一个优先队列即可,优先队列中优先级高的是will高的那个结构体。因为体力消耗是越来越多嘛,所以越后面的就以后面的为基础在继续找。


判断k <= 0时就不停的continue,这样就可以把k = 0 考虑在内了!


接下来就是正常的bfs



代码如下:



#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
const int maxn = 50 + 10;
char mep[maxn][maxn];
int n,m,k,gx,gy,sx,sy;
double dp[maxn][maxn][maxn];
bool vis[maxn][maxn][maxn];
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
const double INF = 1e18;
const double eps = 1e-8;

struct Node{
    int x,y,k;
    double will;
    Node(int x,int y,int k,double will):x(x),y(y),k(k),will(will){}
    bool operator < (const Node&a)const {
        return will > a.will;
    }
};

bool init(int x,int y){
    return x > 0 && x <= n && y > 0 && y <= m && mep[x][y] != '#';
}
void bfs(){
    memset(vis,false,sizeof(vis));
priority_queue<Node>q;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            for (int h = 0; h <=k; ++h)
            dp[i][j][h] = INF;
    q.push(Node(sx,sy,k,0));
    dp[sx][sy][k]=0;
    while(!q.empty()){
        Node u = q.top();q.pop();
        if (vis[u.x][u.y][u.k])continue;
        vis[u.x][u.y][u.k]=true;
        for (int i = 0; i < 4; ++i){
            Node v(u.x+dx[i],u.y+dy[i],u.k-1,u.will);
            if (v.k <= 0 || !init(v.x,v.y))continue;
            v.will+=abs(mep[u.x][u.y] - mep[v.x][v.y])*1.0 / u.k;
            if (dp[v.x][v.y][v.k] > v.will){
                dp[v.x][v.y][v.k] = v.will;
                q.push(v);
            }
        }
    }
}
int main()
{
    int T;
    cin >> T;
    while(T--){
        cin >> n >> m >> k;
        for (int i = 1; i <= n; ++i)scanf("%s",mep[i] + 1);
        cin >> sx >> sy >> gx >> gy;
        if (!k || abs(abs(sx-gx) + abs(gx-sy)) > k){printf("No Answer\n");continue;}
        bfs();
        double ans = INF;
        for (int i = 1; i <= k; ++i)ans = min(ans,dp[gx][gy][i]);
        if (fabs(ans - INF) < eps)printf("No Answer\n");
        else printf("%.2lf\n",ans);
    }
    return 0;
}