大逃亡题解

问题 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 }
View Code
原文地址:https://www.cnblogs.com/liutianrui/p/7470072.html