大逃亡

来源:互联网 发布:好看的网络自制剧 编辑:程序博客网 时间:2024/04/30 19:40

【题目描述】:

给出数字N,X,Y,代表有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 60 0 4 02 12 3

【样例输出】:

2 14

【时间限制、数据范围及描述】:

时间:1s 空间:256M

1<=N<=10000, 1<=X<=1000, 1<=Y<=1000

首先的思路是 大暴力,然而发现数据范围太大。。。

根据伟大的贾老师的题解,终于写出如下代码。。。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#define MAXN 1010#define MAXM 5000010using namespace std;const int dx[4]={0,0,1,-1};const int dy[4]={1,-1,0,0};int n,m,k,head,tail,x1,y1,x2,y2;int x[MAXM],y[MAXM],map[MAXN][MAXN],path[MAXN][MAXN];bool vis[MAXN][MAXN];inline int read(){       int date=0,w=1;char c=0;       while(c!='-'&&(c<'0'||c>'9'))c=getchar();       if(c=='-'){w=-1;c=getchar();}       while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}       return date*w;}void input(){     k=read();n=read();m=read();     head=1;tail=0;     x1=read();y1=read();x2=read();y2=read();     x1++;x2++;y1++;y2++;     for(int i=1;i<=k;i++){             tail++;             x[tail]=read()+1;             y[tail]=read()+1;             vis[x[tail]][y[tail]]=true;             }}void bfs(){     int nx,ny,sx,sy;     while(head<=tail){                       sx=x[head];                       sy=y[head++];                       for(int i=0;i<4;i++){                               nx=sx+dx[i];                               ny=sy+dy[i];                               if(nx<1||nx>n||ny<1||ny>m)continue;                               if(!vis[nx][ny]){                                                vis[nx][ny]=true;                                                map[nx][ny]=map[sx][sy]+1;                                                tail++;                                                x[tail]=nx;y[tail]=ny;                                                }                               }                       }}bool check(int mid){     int nx,ny,sx,sy;     memset(vis,false,sizeof(vis));     memset(path,127,sizeof(path));     head=tail=1;     x[1]=x1;y[1]=y1;     vis[x1][y1]=true;     path[x1][y1]=0;     while(head<=tail){                       sx=x[head];                       sy=y[head++];                       for(int i=0;i<4;i++){                               nx=sx+dx[i];                               ny=sy+dy[i];                               if(nx<1||nx>n||ny<1||ny>m||map[nx][ny]<mid)continue;                               if(!vis[nx][ny]){                                                vis[nx][ny]=true;                                                path[nx][ny]=path[sx][sy]+1;                                                tail++;                                                x[tail]=nx;y[tail]=ny;                                                }                               }                       }     if(vis[x2][y2])     return 1;     else     return 0;}void work(){     int l=0,r=map[x1][y1],mid;     while(l+1<r){                  mid=l+r>>1;                  if(check(mid))l=mid;                  else r=mid;                  }     if(check(r))     printf("%d %d\n",r,path[x2][y2]);     else if(check(l))     printf("%d %d\n",l,path[x2][y2]);}int main(){    input();    bfs();    work();    return 0;}


原创粉丝点击