LYDSY热身赛 escape
Description
给出数字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|
行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你
当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下你最少要走多少步
才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(a,b),(c,d)那么它们的距
离为|a-c|+|b-d|
Input
第一行给出数字N,X,Y
第二行给出x1,y1,x2,y2
下面将有N行,给出N个敌人所在的坐标
第二行给出x1,y1,x2,y2
下面将有N行,给出N个敌人所在的坐标
Output
在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。
Sample Input
2 5 6
0 0 4 0
2 1
2 3
Sample Output
2 14
/* ①灌水法 by hzwer ②二维前缀和 by me ③并查集乱搞 by 某神犇 */ #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<map> #include<vector> #define ll long long #define x1 X1 #define y1 Y1 #define x2 X2 #define y2 Y2 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int ans1,ans2; int head,tail; int n,X,Y; int x1,y1,x2,y2; int mp[1005][1005]; int x[1000005],y[1000005],step[1000005]; bool vis[1005][1005]; int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1}; void pre() { while(head!=tail) { int nx=x[head],ny=y[head];head++; for(int k=0;k<4;k++) { int tx=nx+xx[k],ty=ny+yy[k]; if(tx>=X||ty>=Y||tx<0||ty<0||mp[tx][ty]!=-1)continue; mp[tx][ty]=mp[nx][ny]+1; x[tail]=tx;y[tail]=ty;tail++; } } } int bfs(int val) { head=0;tail=1; if(x1==x2&&y1==y2)return 0; memset(vis,0,sizeof(vis)); vis[x1][y1]=1;x[0]=x1;y[0]=y1; while(head!=tail) { int nx=x[head],ny=y[head],ns=step[head];head++; for(int k=0;k<4;k++) { int tx=nx+xx[k],ty=ny+yy[k]; if(tx>=X||ty>=Y||tx<0||ty<0||mp[tx][ty]<val||vis[tx][ty])continue; vis[tx][ty]=1; if(tx==x2&&ty==y2)return ns+1; x[tail]=tx;y[tail]=ty;step[tail]=ns+1;tail++; } } return -1; } int main() { //freopen("escape.in","r",stdin); //freopen("escape.out","w",stdout); memset(mp,-1,sizeof(mp)); n=read();X=read();Y=read(); x1=read();y1=read();x2=read();y2=read(); for(int i=1;i<=n;i++) { int a=read(),b=read(); mp[a][b]=0; x[tail]=a;y[tail]=b;tail++; } pre(); int l=0,r=mp[x1][y1]; while(l<=r) { int mid=(l+r)>>1; int t=bfs(mid); if(t==-1)r=mid-1; else l=mid+1,ans1=mid,ans2=t; } printf("%d %d\n",ans1,ans2); return 0; } #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int maxn = 10050,inf = 987654; inline int read(){ char ch=getchar(); int f=1,x=0; while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}; while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();}; return x*f; } struct nd{ int x; int y; }; int p,n,m; int ex[maxn],ey[maxn],xa,xb,ya,yb; int flag,dis[1150][1150],vis[1050][1050]; short d[3100][3100],s[3100][3100]; int dx[4] = {1,0,-1,0}; int dy[4] = {0,1,0,-1}; bool emy[3050][3050]; inline bool jud(int x,int y,int t){ if(x < 0 || y < 0 || x >= m || y >= n) return false; if(t == 0) return true; t--; int tx=1005+x-y+t,ty=x+y+t,dx=1005+x-y-t,dy=x+y-t; if(ty>=n+m-1) ty = n+m-2; if(tx>=1005+m) tx = 1004+m; int tot = s[ty][tx]; if(dy>0&&dx>1006-n) tot += s[dy-1][dx-1]; if(dy>0) tot -= s[dy-1][tx]; if(dx>1006-n) tot -= s[ty][dx-1]; if(tot) return false; else return true; } bool check(int t){ if(!jud(xa,ya,t)) return false; flag++; for(int i = 0;i <= n+10;i++){ for(int j = 0;j <= m+10;j++){ dis[i][j] = inf; } } nd now,nxt; now.x = xa; now.y = ya; queue<nd> q; q.push(now); dis[ya][xa] = 0; vis[ya][xa] = flag; while(!q.empty()){ now = q.front(); q.pop(); //cout<<now.y<<" "<<now.x<<endl; for(int dr = 0;dr < 4;dr++){ nxt.x = now.x + dx[dr]; nxt.y = now.y + dy[dr]; if(jud(nxt.x,nxt.y,t)&&vis[nxt.y][nxt.x] != flag){ dis[nxt.y][nxt.x] = dis[now.y][now.x] + 1; vis[nxt.y][nxt.x] = flag; q.push(nxt); if(nxt.y == yb && nxt.x == xb) return true; } } } return false; } int main(){ cin>>p>>m>>n>>xa>>ya>>xb>>yb; for(int i = 1;i <= p;i++){ scanf("%d%d",&ex[i],&ey[i]); emy[ex[i]+ey[i]][1005+ex[i]-ey[i]] = true; } for(int i = 0;i < n + m - 1;i++){ for(int j = 1006-n;j < 1005+m;j++){ if(emy[i][j]) d[i][j] = d[i][j-1] + 1; else d[i][j] = d[i][j-1]; } } for(int i = 0;i < n + m - 1;i++){ for(int j = 1006-n;j < 1005+m;j++){ if(!i) s[i][j] = d[i][j]; else s[i][j] = s[i-1][j] + d[i][j]; } } int l = 0,r = n + m,mid,ans1,ans2; while(l <= r){ mid = (l + r) >> 1; if(check(mid)){ ans1 = mid; ans2 = dis[yb][xb]; l = mid + 1; }else{ r = mid - 1; } } cout<<ans1<<" "<<ans2; return 0; } #include <cstdio> #include <queue> #include <cstring> using namespace std; const int N=10000+5; const int X=1000+5, Y=1000+5; const int pace[4][2]={{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int n, sz_x, sz_y; struct Point { int x, y; inline Point(int _x=0, int _y=0): x(_x), y(_y) {} inline Point walk(int k) { return Point(x+pace[k][0], y+pace[k][1]); } }; Point S, D; int dis_enemy[X][Y]; inline void read_general() { scanf("%d%d%d", &n, &sz_x, &sz_y); scanf("%d%d%d%d", &S.x, &S.y, &D.x, &D.y); } inline void read_enemy_and_process_dis() { memset(dis_enemy, 0x3f, sizeof(dis_enemy)); queue<Point> q; for(int i=1; i<=n; ++i) { Point E; scanf("%d%d", &E.x, &E.y); dis_enemy[E.x][E.y]=0; q.push(E); } while(!q.empty()) { Point U=q.front(); q.pop(); for(int k=0; k<4; ++k) { Point V=U.walk(k); if(V.x<0 || V.x>=sz_x || V.y<0 || V.y>=sz_y || dis_enemy[V.x][V.y]<0x3f3f3f00) continue; dis_enemy[V.x][V.y]=dis_enemy[U.x][U.y]+1; q.push(V); } } } int dis_s[X][Y]; inline int calc_dist(int mid) { memset(dis_s, 0x3f, sizeof(dis_s)); queue<Point> q; if(dis_enemy[S.x][S.y]>=mid) { q.push(S); dis_s[S.x][S.y]=0; } while(!q.empty()) { Point U=q.front(); q.pop(); for(int k=0; k<4; ++k) { Point V=U.walk(k); if(V.x<0 || V.x>=sz_x || V.y<0 || V.y>=sz_y || dis_enemy[V.x][V.y]<mid || dis_s[V.x][V.y]<0x3f3f3f00) continue; dis_s[V.x][V.y]=dis_s[U.x][U.y]+1; q.push(V); } } return dis_s[D.x][D.y]; } int main() { read_general(); read_enemy_and_process_dis(); int l=0, r=100000; while(l<r-1) { int mid=(l+r)>>1; if(calc_dist(mid)<0x3f3f3f00) l=mid; else r=mid; } printf("%d %d\n", l, calc_dist(l)); return 0; }