问题 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
这道题貌似去东北集训的大佬团做过的说,当时心里就有种被坑的感觉,于是默默的想出了正解……
首先这道题第一问一看基本就可以知道可以二分,然后时间复杂度就多了一个log x+y,SPFA一遍大约是O(n),然后时间复杂度就是O(log (x+y)*n)。但是它有一个对于与敌人距离的限制,所以我们还要提前BFS一遍所有点看一下他们到敌人的距离是多少。
顺便说一个坑点,对于每一个二分的距离我们都应首先判断一下起点是否符合否则直接falseQ某犇被这点坑惨了。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<algorithm> 7 #include<cmath> 8 using namespace std; 9 int n,l,r,sx,sy,tx,ty; 10 int dr[10005][2]; 11 int mn[1005][1005]; 12 struct node{ 13 int x,y; 14 int di; 15 }; 16 bool rd[1005][1005]; 17 bool hf(int x,int y){ 18 if(x>=0&&x<l) 19 { 20 if(y>=0&&y<r) 21 return 1; 22 } 23 return 0; 24 } 25 int dis[1005][1005]; 26 void spf1(){ 27 queue<node> q1; 28 memset(rd,0,sizeof(rd)); 29 for(int i=1;i<=n;i++) 30 { 31 node aa; 32 aa.x=dr[i][0],aa.y=dr[i][1]; 33 rd[dr[i][0]][dr[i][1]]=1; 34 mn[dr[i][0]][dr[i][1]]=0; 35 aa.di=0; 36 q1.push(aa); 37 } 38 while(!q1.empty()) 39 { 40 node bb=q1.front(); 41 q1.pop(); 42 int x=bb.x,y=bb.y; 43 rd[x][y]=0; 44 if(hf(x-1,y)&&mn[x-1][y]>mn[x][y]+1) 45 { 46 mn[x-1][y]=mn[x][y]+1; 47 if(!rd[x-1][y]) 48 { 49 rd[x-1][y]=1; 50 node cc; 51 cc.x=x-1,cc.y=y; 52 q1.push(cc); 53 } 54 } 55 if(hf(x+1,y)&&mn[x+1][y]>mn[x][y]+1) 56 { 57 mn[x+1][y]=mn[x][y]+1; 58 if(!rd[x+1][y]) 59 { 60 rd[x+1][y]=1; 61 node cc; 62 cc.x=x+1,cc.y=y; 63 q1.push(cc); 64 } 65 } 66 if(hf(x,y-1)&&mn[x][y-1]>mn[x][y]+1) 67 { 68 mn[x][y-1]=mn[x][y]+1; 69 if(!rd[x][y-1]) 70 { 71 rd[x][y-1]=1; 72 node cc; 73 cc.x=x,cc.y=y-1; 74 q1.push(cc); 75 } 76 } 77 if(hf(x,y+1)&&mn[x][y+1]>mn[x][y]+1) 78 { 79 mn[x][y+1]=mn[x][y]+1; 80 if(!rd[x][y+1]) 81 { 82 rd[x][y+1]=1; 83 node cc; 84 cc.x=x,cc.y=y+1; 85 q1.push(cc); 86 } 87 } 88 } 89 } 90 int ans[2]; 91 bool check(int L){ 92 if(mn[sx][sy]<L) 93 return 0; 94 node aa; 95 aa.x=sx,aa.y=sy; 96 memset(rd,0,sizeof(rd)); 97 memset(dis,0x3f,sizeof(dis)); 98 int tmp=dis[0][0]; 99 dis[sx][sy]=0; 100 rd[sx][sy]=1; 101 queue<node> q1; 102 q1.push(aa); 103 while(!q1.empty()) 104 { 105 node bb; 106 bb=q1.front(); q1.pop(); 107 int x=bb.x,y=bb.y; 108 rd[x][y]=0; 109 if(hf(x-1,y)&&dis[x-1][y]>dis[x][y]+1&&mn[x-1][y]>=L) 110 { 111 dis[x-1][y]=dis[x][y]+1; 112 if(!rd[x-1][y]) 113 { 114 rd[x-1][y]=1; 115 node cc; 116 cc.x=x-1,cc.y=y; 117 q1.push(cc); 118 } 119 } 120 if(hf(x+1,y)&&dis[x+1][y]>dis[x][y]+1&&mn[x+1][y]>=L) 121 { 122 dis[x+1][y]=dis[x][y]+1; 123 if(!rd[x+1][y]) 124 { 125 rd[x+1][y]=1; 126 node cc; 127 cc.x=x+1,cc.y=y; 128 q1.push(cc); 129 } 130 } 131 if(hf(x,y-1)&&dis[x][y-1]>dis[x][y]+1&&mn[x][y-1]>=L) 132 { 133 dis[x][y-1]=dis[x][y]+1; 134 if(!rd[x][y-1]) 135 { 136 rd[x][y-1]=1; 137 node cc; 138 cc.x=x,cc.y=y-1; 139 q1.push(cc); 140 } 141 } 142 if(hf(x,y+1)&&dis[x][y+1]>dis[x][y]+1&&mn[x][y+1]>=L) 143 { 144 dis[x][y+1]=dis[x][y]+1; 145 if(!rd[x][y+1]) 146 { 147 rd[x][y+1]=1; 148 node cc; 149 cc.x=x,cc.y=y+1; 150 q1.push(cc); 151 } 152 } 153 } 154 if(tmp==dis[tx][ty]) 155 return 0; 156 ans[0]=L; 157 ans[1]=dis[tx][ty]; 158 return 1; 159 } 160 int main(){ 161 memset(mn,0x3f,sizeof(mn)); 162 scanf("%d%d%d",&n,&l,&r); 163 scanf("%d%d%d%d",&sx,&sy,&tx,&ty); 164 for(int i=1;i<=n;i++) 165 scanf("%d%d",&dr[i][0],&dr[i][1]); 166 spf1(); 167 int li=0,ri=l+r; 168 while(li<=ri) 169 { 170 int mid=(li+ri)/2; 171 if(check(mid)) 172 li=mid+1; 173 else 174 ri=mid-1; 175 } 176 printf("%d %d",ans[0],ans[1]); 177 //while(1); 178 return 0; 179 }