题目链接
分析
这个题最大的突破口在 积水点 很少 小于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;
}
}