• bfs 大逃亡


    问题 C: 大逃亡
    时间限制: 1 Sec 内存限制: 256 MB
    题目描述
    给出数字N(1<=N<=10000),X(1<=x<=1000),Y(1<=Y<=1000),代表有N个敌人分布一个X行Y列的矩阵上,矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下,你最少要走多少步才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(a,b),(c,d),那么它们的距离为|a-c|+|b-d|。
    输入
    第一行给出数字N,X,Y
    第二行给出x1,y1,x2,y2
    下面将有N行,给出N个敌人所在的坐标。
    输出
    在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。
    样例输入
    2 5 6
    0 0 4 0
    2 1
    2 3
    样例输出
    2 14

    明显是广搜,首先处理出每个点到敌人最小距离,然后因为答案一定是满足单调性的,如果某一个距离满足,那比他小的一定不是最优,因此就可以二分了满足条件就是终点能被更新)
    我考试时打了两遍spfa,一遍处理出了到终点的最大距离。。然后果断T了两个点。。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define N 1005
    using namespace std;
    int read()
    {
        int sum=0,f=1;char x=getchar();
        while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
        while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}
        return sum*f;
    }
    struct zb{int x,y;}S,T;
    int n,ans,s,X,Y,dis[N][N],vis[N][N],d[N][N];
    int wz[5][2]={0,-1,-1,0,0,1,1,0};
    queue<zb> q;
    inline void bfs()
    {
        while(!q.empty())
        {
            zb x=q.front();
            for(int i=0;i<4;i++)
            {
                zb k;k.x=x.x+wz[i][0],k.y=x.y+wz[i][1];
                if(k.x<0||k.x>=X||k.y<0||k.y>=Y)continue;
                if(dis[k.x][k.y]>dis[x.x][x.y]+1)
                {
                    dis[k.x][k.y]=dis[x.x][x.y]+1;
                    if(!vis[k.x][k.y])
                    {
                        vis[k.x][k.y]=1;
                        q.push(k);
                    }
                }
            }
            vis[x.x][x.y]=0;q.pop();
        }
    }
    inline bool spfa2(int m)
    {
        if(dis[S.x][S.y]<m||dis[T.x][T.y]<m)return 0;
        vis[S.x][S.y]=1;d[S.x][S.y]=0;
        q.push(S);
        while(!q.empty())
        {
            zb x=q.front();
            for(int i=0;i<4;i++)
            {
                zb k;k.x=x.x+wz[i][0],k.y=x.y+wz[i][1];
                if(k.x<0||k.x>=X||k.y<0||k.y>=Y||dis[k.x][k.y]<m)continue;
                if(d[k.x][k.y]>d[x.x][x.y]+1)
                {
                    d[k.x][k.y]=d[x.x][x.y]+1;
                    if(!vis[k.x][k.y])
                    {
                        vis[k.x][k.y]=1;
                        q.push(k);
                    }
                }
            }
            q.pop();vis[x.x][x.y]=0;
        }
        if(d[T.x][T.y]<100000){s=m;ans=d[T.x][T.y];return 1;}
        return 0;
    }
    int main()
    {
        n=read();X=read();Y=read();
        S.x=read();S.y=read();
        T.x=read();T.y=read();
        memset(dis,60,sizeof(dis));
        for(int i=1;i<=n;i++)
        {
            zb x;x.x=read();x.y=read();
            vis[x.x][x.y]=1;dis[x.x][x.y]=0;q.push(x);
        }
        bfs();
        int l=0,r=X+Y,mid;
        while(l<=r)
        {
            memset(d,60,sizeof(d));
            mid=(l+r)/2;
            if(spfa2(mid))l=mid+1;
            else r=mid-1;
        }
        printf("%d %d
    ",s,ans);
    }
  • 相关阅读:
    ADO.NET 实体框架 资料收集
    sql server 根据执行计划查询耗时操作
    查看sql server数据库文件信息
    TypeScript
    使用mustache.js 模板引擎输出html
    C#委托多播、Lambda表达、多线程、任务
    PID控制器开发笔记之十三:单神经元PID控制器的实现
    C语言学习及应用笔记之五:C语言typedef关键字及其使用
    君子爱财
    PID控制器开发笔记之十二:模糊PID控制器的实现
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632688.html
Copyright © 2020-2023  润新知