• poj 3897 Maze Stretching 二分+A*搜索


    题意,给你一个l,和一个地图,让你从起点走到终点,使得路程刚好等于l。

    你可以选择一个系数,把纵向的地图拉伸或收缩,比如你选择系数0.5,也就是说现在上下走一步消耗0.5的距离,如果选择系数3,也就是说上下一步消耗3的距离。

    左右不能改变。


    Hint中提示了答案在0--10之间,其实就透露出了二分的思想。

    我们对系数P进行二分,对每一个系数P进行一次bfs,如果可以在小于等于l的步数内找到解,则增加下界,否则减小上界。


    由于上下和左右的消耗值不相同,所以我们采用A*算法,设估价值为当前点到目标点的哈弗曼距离(注意上下距离要乘上系数P),然后利用优先队列搜索。

    我试了几下,精度开到1e-6才不会wa

    如果用普通的bfs做,注意不能一遇到终点就结束,有可能丢失掉最优解。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<iostream>
    using namespace std;
    char map[105][105];
    int CAS;
    double l;
    int n,len;
    int end,st;
    int dx[]={-1,1,0,0};
    int dy[]={0,0,-1,1};
    struct node
    {
        double dis;
        int x;
        int y;
        double h;
        bool operator < (const node &a) const
        {
            return dis+h>a.dis+h;
        }
    }start;
    double geth(int x,int y,double k)
    {
        double h=0;
        int ex=end/len;
        int ey=end%len;
        return abs(ey-y)+abs(ex-x)*k;
    }
    bool isok(int x,int y)
    {
        return x>=0&&x<n&&y>=0&&y<len&&map[x][y]!='#';
    }
    double vis[105][105];
    bool bfs(double k)
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<len;j++)
                vis[i][j]=100000000;
        priority_queue<node> q;
        q.push(start);
        vis[start.x][start.y]=1;
        node tmp,tt;
        while(!q.empty())
        {
            tmp=q.top();q.pop();
            for(int d=0;d<4;d++)
            {
                tt=tmp;
                tt.x=tmp.x+dx[d];
                tt.y=tmp.y+dy[d];
                if(isok(tt.x,tt.y))
                {
                    tt.h=geth(tt.x,tt.y,k);
                    if(d<=1) tt.dis+=k;
                    else tt.dis+=1;
                    if(tt.dis<vis[tt.x][tt.y]) vis[tt.x][tt.y]=tt.dis;
                    else continue;
    
                    if(tt.x==end/len&&tt.y==end%len)
                    {
                        if(tt.dis<=l) return true;
                        else return false;
                    }
                    q.push(tt);
                }
            }
        }
        return false;
    }
    int main()
    {
        int cas;
        CAS=1;
        scanf("%d",&cas);
        while(cas--)
        {
            scanf("%lf%d",&l,&n);getchar();
            for(int i=0;i<n;i++)
                gets(map[i]);
            len=strlen(map[0]);
            for(int i=0;i<n;i++)
                for(int j=0;j<len;j++)
                {
                    if(map[i][j]=='S')
                    {
                        st=i*len+j;
                    }
                    if(map[i][j]=='E')
                    {
                        end=i*len+j;
                    }
                }
            start.dis=0;
            start.x=st/len;
            start.y=st%len;
            double l=0;
            double r=11;
            double mid=(l+r)/2.0;
            while(r-l>1e-6)
            {
         //     cout<<l<<' '<<r<<' '<<mid<<endl;
                mid=(l+r)/2.0;
                if(bfs(mid)) l=mid;
                else r=mid;
            }
            printf("Case #%d: %.3f%%
    ",CAS++,mid*100);
        }
        return 0;
    }
    

    /*

    我是一只奔跑的小菜鸡……

    */

  • 相关阅读:
    MFC project for a non-Unicode character set is deprecated
    关于Visual Studio 2013 编译 multi-byte character set MFC程序出现 MSB8031 错误的解决办法
    字符串比较自实现
    各种语言里获取当前模块的方法:ABAP,ABSL,C,nodejs
    SAP CRM product attachment的document template功能
    ABAP, UI5和webpack的处理入口
    ABAP, Maven, CF App和Webpack的build
    json格式的字符串序列化和反序列化的一些高级用法
    SAP ABAP Netweaver容器化, 不可能完成的任务吗?
    UI Component in CRM WebUI and Hybris
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3198831.html
Copyright © 2020-2023  润新知