【A*搜索,BFS搜索】poj3897Maze Stretching

题目描述:给定一个l,和一个地图,让你从起点走到终点,使得路程刚好等于l。可以选择一个系数,把纵向的地图拉伸或收缩,比如你选择系数0.5,也就是说现在上下走一步消耗0.5的距离,如果选择系数3,也就是说上下一步消耗3的距离。求这个系数。

建议大家去poj看看原题比较好,因为他给定了答案的范围在1-10之间。这提示我们用二分答案来做。
之后对给定的系数做一次最短路来判断路程是否为l。
显然可以用BFS+优先队列做。但都用了优先队列了,为何不加一个估值函数呢?
估值函数:该点到终点的哈密顿距离
蒟蒻不才,只写了特慢超长代码……
不过在进步的路上要接受自己的无知
蒟蒻加油 ↖(^ω^)↗

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define END 0.000001
#define MAXN 205
#define INF 1<<30
using namespace std;

int len ,bx ,by ,ex ,ey ,n ,m ;
int dd[4][2]={0,1,0,-1,1,0,-1,0};
char map[MAXN][MAXN] ;
bool visit[MAXN][MAXN] ;
double dis ,l ,r ,mid ,d[MAXN][MAXN] ;

struct node
{
    int x ,y ;
    double step ;
    node(){}
    node(const int a,const int b,const double c)
    {
        x=a ,y=b ,step=c ;
    }
    bool operator < (const node a) const
    {
        return step>a.step;
    }
}temp;

bool check(int x,int y)
{
    if(x<1||x>n||y<1||y>m)
        return 0;
    if(map[x][y]=='#'||visit[x][y])
        return 0;
    return 1;
}

double bfs()
{
    int dx ,dy ;
    priority_queue<node>point;
    point.push(node(bx,by,0));

    memset(visit,0,sizeof(visit));
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            d[i][j]=INF;

    while(!point.empty())
    {
        temp=point.top();
        point.pop();

        visit[temp.x][temp.y]=1;
        if(temp.x==ex&&temp.y==ey)
            return temp.step;
        for(int i=0;i<4;++i)
        {
            dx=temp.x+dd[i][0],dy=temp.y+dd[i][1];
            if(check(dx,dy))
            {
                if(i<2)
                {
                    if(d[dx][dy]>temp.step+1)
                    {
                        d[dx][dy]=temp.step+1;
                        point.push(node(dx,dy,temp.step+1));
                    }
                }
                else
                {
                    if(d[dx][dy]>temp.step+mid)
                    {
                        d[dx][dy]=temp.step+mid;
                        point.push(node(dx,dy,temp.step+mid));
                    }
                }
            }
        }
    }
    return 0;
}

int main()
{
    int T ,code=0 ;
    scanf("%d",&T);
    while(T--)
    {
        memset(visit,0,sizeof(visit));
        bx=by=ex=ey=0;
        scanf("%lf%d",&dis,&n);
        for(int i=1;i<=n;++i)
        {
            getchar();
            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')
                    bx=i,by=j;
                else if(map[i][j]=='E')
                    ex=i,ey=j;
                if(bx&&by&&ex&&ey)
                    break;
            }
            if(bx&&by&&ex&&ey)
                break;
        }
        l=0 ,r=10.0 ;
        while(r-l>END)
        {
            mid=(l+r)/2.0;
            if(bfs()<dis+END)
                l=mid;
            else r=mid;
        }
        printf("Case #%d: %.3f%%\n",++code,mid*100.0);
    }
    return 0;
}

你可能感兴趣的:(搜索,bfs,poj3897)