zoukankan      html  css  js  c++  java
  • 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|

    Input

    第一行给出数字N,X,Y 
    第二行给出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
    ",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
    ", l, calc_dist(l));
        return 0;
    }
     
  • 相关阅读:
    Java实现第十届蓝桥杯旋转
    Java实现第十届蓝桥杯旋转
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯最大降雨量
    Java实现第十届蓝桥杯质数
    【JSP EL】EL表达式获取当前时间(两种方式)
    23种设计模式总结
  • 原文地址:https://www.cnblogs.com/hyfer/p/5918124.html
Copyright © 2011-2022 走看看