大逃亡

问题 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
solution:
    
很明显的二分加暴搜,dfs,bfs均可,不过本菜鸟比较倾向于bfs,很好实现,每次二分前预处理这个点在当前长度下周围是否有敌人,然后bfs即可,考试的时候因为保留字被坑了,100分白白扔了。
      
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 __attribute__((optimize("O3")))int read() {
  7     int s=0,f=1;
  8     char ch=getchar();
  9     for( ; ch<'0'||ch>'9'; f=(ch=='-')?(-1):(f),ch=getchar()) ;
 10     for( ; ch>='0'&&ch<='9'; s=(s<<1)+(s<<3)+(ch^48),ch=getchar()) ;
 11     return s*f;
 12 }
 13 int n,asdsasadsadsadsad,adsgfasdfdsafadsfdsaf,qq,asdsadsadsad,asdsa,asdfadsfadsfadsfd,ans1,ans2,step[1001][1001];
 14 int tox[4]= {1,-1,0,0},toy[4]= {0,0,1,-1};
 15 bool walk[1001][1001];
 16 struct ii {
 17     int x,y;
 18 } ee[10005];
 19 int abs(int x) {
 20     return x<0?(-x):(x);
 21 }
 22 int head,tail;
 23 struct oo {
 24     int x,y;
 25 } que[20000005];
 26 __attribute__((optimize("O3")))bool init(int dis) {
 27     memset(walk,true,sizeof(walk));
 28     for(int i=1; i<=n; ++i) {
 29         int x=ee[i].x,y=ee[i].y;
 30         for(int j=x; abs(x-j)<dis&&j; --j) {
 31             int ji=abs(x-j);
 32             for(int k=y; ji+abs(k-y)<dis&&k; --k) {
 33                 walk[j][k]=false;
 34                 if(!walk[qq][asdsadsadsad]) {
 35                     return false;
 36                 }
 37             }
 38             for(int k=y; ji+abs(k-y)<dis&&k<=adsgfasdfdsafadsfdsaf; ++k) {
 39                 walk[j][k]=false;
 40                 if(!walk[qq][asdsadsadsad]) {
 41                     return false;
 42                 }
 43             }
 44         }
 45         for(int j=x; abs(x-j)<dis&&j<=asdsasadsadsadsad; ++j) {
 46             int ji=abs(x-j);
 47             for(int k=y; ji+abs(k-y)<dis&&k; --k) {
 48                 walk[j][k]=false;
 49                 if(!walk[qq][asdsadsadsad]) {
 50                     return false;
 51                 }
 52             }
 53             for(int k=y; ji+abs(k-y)<dis&&k<=adsgfasdfdsafadsfdsaf; ++k) {
 54                 walk[j][k]=false;
 55                 if(!walk[qq][asdsadsadsad]) {
 56                     return false;
 57                 }
 58             }
 59         }
 60     }
 61     memset(step,0x5f,sizeof(step));
 62     step[qq][asdsadsadsad]=0;
 63     if(!walk[qq][asdsadsadsad]) {
 64         return false;
 65     } else {
 66         return true;
 67     }
 68 }
 69 __attribute__((optimize("O3")))int bfs(int u) {
 70     head=tail=0;
 71     que[++tail]=(oo) {
 72         qq,asdsadsadsad
 73     };
 74     while(head<tail) {
 75         int x=que[++head].x,y=que[head].y;
 76         if(x==asdsa&&y==asdfadsfadsfadsfd) {
 77             continue;
 78         }
 79         for(int i=0; i<4; ++i) {
 80             if(x+tox[i]>0&&x+tox[i]<=asdsasadsadsadsad) {
 81                 if(y+toy[i]>0&&y+toy[i]<=adsgfasdfdsafadsfdsaf) {
 82                     if(step[x+tox[i]][y+toy[i]]>step[x][y]+1&&walk[x+tox[i]][y+toy[i]]) {
 83                         step[x+tox[i]][y+toy[i]]=step[x][y]+1;
 84                         que[++tail]=(oo) {
 85                             x+tox[i],y+toy[i]
 86                         };
 87                     }
 88                 }
 89             }
 90         }
 91     }
 92     return step[asdsa][asdfadsfadsfadsfd];
 93 }
 94 __attribute__((optimize("O3")))void two_divi() {
 95     int l=0,r=adsgfasdfdsafadsfdsaf+asdsasadsadsadsad;
 96     while(l<r) {
 97         int mid=(l+r)>>1;
 98         bool pd=init(mid);
 99         if(!pd) {
100             r=mid;
101             continue;
102         }
103         int check=bfs(mid);
104         if(check!=1600085855) {
105             ans2=step[asdsa][asdfadsfadsfadsfd];
106             ans1=mid;
107             l=mid+1;
108         } else {
109             r=mid;
110         }
111     }
112 }
113 __attribute__((optimize("O3")))int main() {
114     n=read(),asdsasadsadsadsad=read(),adsgfasdfdsafadsfdsaf=read();
115     qq=read()+1,asdsadsadsad=read()+1,asdsa=read()+1,asdfadsfadsfadsfd=read()+1;
116     for(int x,y,i=1; i<=n; ++i) {
117         x=read()+1,y=read()+1;
118         ee[i].x=x,ee[i].y=y;
119     }
120     two_divi();
121     printf("%d %d",ans1,ans2);
122     return 0;
123 }

 

 

转载于:https://www.cnblogs.com/forevergoodboy/p/7470254.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值