问题 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 }