hihocoder 1368 积水的城市2(离散化+dijstra)

题目链接

hihocoder 1368 积水的城市2

分析

这个题最大的突破口在 积水点 很少 小于30, 也就是说,这个图中大部分点是没用的,只需记录这30个点和他旁边的点就好,这不就是离散化吗??关于离散化,不得不说 matrix67,写的很到位。matrix67 离散化

其实二维离散化与一维一点区别也没有啊,我们完全可以将点的坐标沿着X,Y轴离散化后,再在两个轴中找到具体二维点的定位,

e.g : X : [0,5,6,7] ,Y[0,8,9,10]

那么 (5,8) 对应的就是 (1,2) 将它在二维的图中标记好就可以了

Java code

import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Scanner;




public class Main {
    public static Scanner in = new Scanner(new BufferedInputStream(System.in));
    public static final int INF32 = 0x3f3f3f3f;
    public static final int MAXN = 90+5;
    public static final int MAXN_LEN = 1000+10;
    public static boolean[][] G = new boolean[MAXN][MAXN];
    public static int[] x,y;
    public static int k,n,m,x1,x2,y1,y2;
    public static HashMap<Integer, Integer> xf,yf;
    public static int[] sumx = new int[MAXN_LEN],sumy = new int[MAXN_LEN];
    private static ArrayList<Integer> xIdx,yIdx;
    public static void main(String[] args) {
        n = in.nextInt();
        m = in.nextInt();
        sumx[0] =0;
        for(int i=1 ; i<n ; ++i){
            sumx[i] = sumx[i-1]+in.nextInt();
        }
        sumy[0] =0;
        for(int i=1 ; i<m ; ++i){
            sumy[i] = sumy[i-1]+in.nextInt();
        }
        k = in.nextInt();
        x = new int[k];
        y = new int[k];
        for(int i=0 ; i<k ; ++i){
            x[i] = in.nextInt()-1;
            y[i] = in.nextInt()-1;
        }
        int Q = in.nextInt();
        while (Q-->0) {
            x1 = in.nextInt()-1;
            y1 = in.nextInt()-1;
            x2 = in.nextInt()-1;
            y2 = in.nextInt()-1;
            System.out.println(solve());
        }
    }
    //离散化
    private static ArrayList<Integer> compass(int [] val,boolean isX) {
        HashSet<Integer> tmp = new HashSet<>();
        int len=0;
        if(isX){
            len = n;tmp.addAll(Arrays.asList(x1,x2));
        }
        else {
            len = m;tmp.addAll(Arrays.asList(y1,y2));
        }
        tmp.addAll(Arrays.asList(0,len-1));
        for(Integer e: val){
            for(int i=-1 ; i<=1 ; ++i)
                if(e+i >=0 && e+i <len)tmp.add(e+i);
        }
        ArrayList<Integer> ret = new ArrayList<>(tmp);
        Collections.sort(ret);
        return ret;
    }
    public static int solve() {
        //if(Math.abs(x2-x1) >k && Math.abs(y1-y2)>k)return Math.abs(sumx[x2]-sumx[x1]) + Math.abs(sumy[y1]-sumy[y2]);
        xIdx = compass(x, true);
        yIdx = compass(y, false);
        xf = new HashMap<>();
        yf = new HashMap<>();

//      for(int i=0 ; i<xIdx.size() ; ++i)System.out.print(xIdx.get(i));System.out.println();
//      for(int i=0 ; i<yIdx.size() ; ++i)System.out.print(yIdx.get(i));System.out.println();
//      
        for(int i=0 ; i<xIdx.size() ; ++i)
            for(int j=0 ; j<yIdx.size() ; ++j){
                G[i][j] = true;dist[i][j]=INF32;
            }
        for(int i=0 ; i<k ; ++i){
            int xi = Collections.binarySearch(xIdx, x[i]);
            int yi = Collections.binarySearch(yIdx, y[i]);
            G[xi][yi] = false;
        }
//      for(int i=0 ; i<xIdx.size() ; ++i){
//          for(int j=0 ; j<yIdx.size() ; ++j){
////                G[i][j] = true;dist[i][j]=INF32;
//              System.out.print(G[i][j]+" ");
//          }
//          System.out.println();
//      }
        int sx = Collections.binarySearch(xIdx, x1);
        int sy = Collections.binarySearch(yIdx, y1);
        int ex = Collections.binarySearch(xIdx, x2);
        int ey = Collections.binarySearch(yIdx, y2);

        return dijstra(sx, sy, ex, ey);
    }
    //PQ Node
    static class Node implements Comparable<Node>{
        int px,py;
        int val;
        @Override

        public int compareTo(Node o) {
            // TODO Auto-generated method stub
            return val - o.val;
        }
        public Node(int px, int py, int val) {
            super();
            this.px = px;
            this.py = py;
            this.val = val;
        }

    }
    private static int[][] dist = new int[MAXN][MAXN];
    private static int[] dx = new int[]{1,-1,0,0};
    private static int[] dy = new int[]{0,0,1,-1};
    //求距离
    private static int distance(int ix,int iy,int[] sum,ArrayList<Integer> idx) {
        int fx = idx.get(ix),fy = idx.get(iy);
        return Math.abs(sum[fy]-sum[fx]);
    }
    private static boolean isLegalPoint(int nx,int ny) {
        return nx<xIdx.size() && nx >=0 && ny >=0 && ny < yIdx.size() &&G[nx][ny];
    }
    private static int dijstra(int sx,int sy,int ex,int ey){
        PriorityQueue<Node> Q = new PriorityQueue<>();
        dist[sx][sy] =0;
        Q.add(new Node(sx, sy, 0));
        while (!Q.isEmpty()) {
            Node now = Q.remove();
            if(now.val > dist[now.px][now.py])continue;
            if(now.px ==ex&&now.py == ey)return now.val;
            for(int i=0 ; i<4 ; ++i){
                int nx = now.px+dx[i];
                int ny = now.py + dy[i];
                if(!isLegalPoint(nx, ny))continue;
                int cost =0;
                if(dx[i]!=0)cost += distance(nx, now.px, sumx,xIdx);
                if(dy[i]!=0)cost += distance(ny, now.py, sumy,yIdx);
                if(dist[nx][ny] >dist[now.px][now.py] + cost){
                    dist[nx][ny] = dist[now.px][now.py] + cost;
                    Q.add(new Node(nx, ny, dist[nx][ny]));
                }
            }
        }
        return -1;
    }
}

猜你喜欢

转载自blog.csdn.net/dylan_frank/article/details/80113186