【图论】【启发式搜索】【二分查找】[POJ 3897]Maze Stretching

启发式搜索主要就是加速,其实不用也可以过。二分L然后每次看最短路是多少,估价函数就是曼哈顿距离,然后注意精度误差就好了Tip:在POJ上交这道题目记得用c++千万不要用g++

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 100;
const double eps = 1e-6;
double f[MAXN+5][MAXN+5], L;
int n, m;
char Map[MAXN+5][MAXN+5];
struct State{
    int x, y;
    double f, g, h;
    bool operator < (const State &s) const {
        return f > s.f;
    }
};
priority_queue<State> que;
double mabs(double d){return d>0?d:-d;}
double _h(State s, int tox, int toy, int p){
    return 1.0 * mabs(s.x - tox) * p + 1.0 * mabs(s.y - toy);
}
double Astar(int stx, int sty, int tox, int toy, double P){
    while(!que.empty()) que.pop();
    for(int i=1;i<=100;i++)
        for(int j=1;j<=100;j++)
            f[i][j] = 100000000;
    State tmp, tmp2;
    tmp.x = stx, tmp.y = sty;
    tmp.g = 0, tmp.h = _h(tmp, tox, toy, P);
    tmp.f = tmp.g + tmp.h;
    f[tmp.x][tmp.y] = tmp.f;
    que.push(tmp);
    while(!que.empty()){
        tmp = que.top(); que.pop();
        if(tmp.x == tox && tmp.y == toy)
            return tmp.g;
        if(tmp.x > 1 && Map[tmp.x-1][tmp.y] != '#'){
            tmp2 = tmp; tmp2.x --;
            tmp2.g += P; tmp2.h = _h(tmp2, tox, toy, P);
            tmp2.f = tmp2.g + tmp2.h;
            if(tmp2.f < f[tmp2.x][tmp2.y]){
                f[tmp2.x][tmp2.y] = tmp2.f;
                que.push(tmp2);
            }
        }
        if(tmp.x < n && Map[tmp.x+1][tmp.y] != '#'){
            tmp2 = tmp; tmp2.x ++;
            tmp2.g += P; tmp2.h = _h(tmp2, tox, toy, P);
            tmp2.f = tmp2.g + tmp2.h;
            if(tmp2.f < f[tmp2.x][tmp2.y]){
                f[tmp2.x][tmp2.y] = tmp2.f;
                que.push(tmp2);
            }
        }
        if(tmp.y > 1 && Map[tmp.x][tmp.y-1] != '#'){
            tmp2 = tmp; tmp2.y --;
            tmp2.g += 1; tmp2.h = _h(tmp2, tox, toy, P);
            tmp2.f = tmp2.g + tmp2.h;
            if(tmp2.f < f[tmp2.x][tmp2.y]){
                f[tmp2.x][tmp2.y] = tmp2.f;
                que.push(tmp2);
            }
        }
        if(tmp.y < m && Map[tmp.x][tmp.y+1] != '#'){
            tmp2 = tmp; tmp2.y ++;
            tmp2.g += 1; tmp2.h = _h(tmp2, tox, toy, P);
            tmp2.f = tmp2.g + tmp2.h;
            if(tmp2.f < f[tmp2.x][tmp2.y]){
                f[tmp2.x][tmp2.y] = tmp2.f;
                que.push(tmp2);
            }
        }
    }
    return -1.0;
}
int Tcnt;
void solve(){
    memset(Map, 0, sizeof Map);
    scanf("%lf%d\n", &L, &n);
    double l = 0.0, r = 10.0, mid, len, sx, sy, ex, ey, P;
    for(int i=1;i<=n;i++){
        gets(Map[i]+1);
    }
    m = strlen(Map[1] + 1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(Map[i][j] == 'S'){
                sx = i, sy = j;
            }else if(Map[i][j] == 'E'){
                ex = i, ey = j;
            }
        }
    }
    while(l < r){
        mid = (l + r) / 2.0;
        len = Astar(sx, sy, ex, ey, mid);
        if(len+eps >= L && len-eps <= L){
            P = mid;
            break;
        }else if(len > L){
            r = mid;
        }else{
            l = mid;
        }
    }
    printf("Case #%d: %.3lf%%\n", ++Tcnt, P*100.0);
}
int main(){
    int K;
    scanf("%d", &K);
    while(K--){
        solve();
    }

    return 0;
}

posted on 2015-07-27 14:44  JeremyGuo  阅读(207)  评论(0编辑  收藏  举报

导航