東北育才 day6 T3 大逃亡
阿新 • • 發佈:2017-06-27
set names 最小 iostream stp lose opened escape 問題
大逃亡(escape)
【問題描述】
給出數字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|。
【輸入格式】
第一行3 個整數為N,X,Y
第二行4 個整數為x1,y1,x2,y2
下面將有N 行,為N 個敵人所在的坐標。
【輸出格式】
在一行內輸出你離敵人的距離及在這個距離的限制下,你到目標點最少要移動多少步。
【樣例輸入】
2 5 6
0 0 4 0
2 1
2 3
【樣例輸出】
2 14
最大化最小值,很明顯二分後驗證;
敵人位置固定,所以每一個點距最近敵人距離固定;
求曼哈頓距離,所以以每個敵人為起始點四連通bfs,每個點第一次一定是被最近的敵人訪問;
復雜度方面,每個點只會被上下左右四個點各訪問一次,所以預處理是O(4*n^2);
預處理後直接bfs全圖驗證,復雜度O(n^2);
AC GET☆DAZE
代碼 ↓
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #defineView CodeMAX_N 39393939 #define ll long long using namespace std; struct poi { ll x,y; }; ll sum=0; poi que[1000039]; ll ansdis[1039][1039],dis[1039][1039],h=1,t=0,mx[4]={1,0,-1,0},my[4]={0,1,0,-1},X,Y,sx,sy,dx,dy,x,y; bool check[1039][1039]={0}; bool inmap(ll x,ll y) { if(x<0 || y<0 || x>=X || y>=Y) {return 0; } return 1; } bool checkans(ll d) { if(dis[x][y]<d) { return 0; } memset(check,0,sizeof(check)); poi stp; ll a,b,c; stp.x=sx,stp.y=sy; h=1,t=0,que[++t]=stp; while(h<=t) { sum++; x=que[h].x,y=que[h].y; if(x==dx && y==dy) { return 1; } for(a=0;a<=3;a++) { x+=mx[a],y+=my[a]; if(inmap(x,y) && dis[x][y]>=d && !check[x][y]) { stp.x=x,stp.y=y; que[++t]=stp; check[x][y]=1; ansdis[x][y]=min(ansdis[x][y],ansdis[que[h].x][que[h].y]+1); } x-=mx[a],y-=my[a]; } h++; } return 0; } int main() { memset(dis,-1,sizeof(dis)); poi stp; ll n,le,ri,mi,a,b,c; scanf("%lld%lld%lld",&n,&X,&Y); scanf("%lld%lld%lld%lld",&sx,&sy,&dx,&dy); for(a=1;a<=n;a++) { scanf("%lld%lld",&stp.x,&stp.y); dis[stp.x][stp.y]=0; que[a]=stp; check[stp.x][stp.y]=1; } t=n; ri=0; while(h<=t) { x=que[h].x,y=que[h].y; for(a=0;a<=3;a++) { x+=mx[a],y+=my[a]; if(inmap(x,y) && dis[x][y]==-1) { stp.x=x,stp.y=y; que[++t]=stp; dis[stp.x][stp.y]=dis[que[h].x][que[h].y]+1; ri=max(ri,dis[stp.x][stp.y]); } x-=mx[a],y-=my[a]; } h++; } le=1; while(le+10<ri) { mi=(le+ri)>>1; if(checkans(mi)) { le=mi; } else { ri=mi-1; } } while(!checkans(ri)) { ri--; } for(a=0;a<X;a++) { for(b=0;b<Y;b++) { ansdis[a][b]=MAX_N; } } ansdis[sx][sy]=0; checkans(ri); printf("%lld %lld",ri,ansdis[dx][dy]); return 0; }
東北育才 day6 T3 大逃亡