Shopee物流会有很多个中转站。在选址的过程中,会选择离用户最近的地方建一个物流中转站。
假设给你一个二维平面网格,每个格子是房子则为1,或者是空地则为0。找到一个空地修建一个物流中转站,使得这个物流中转站到所有的房子的距离之和最小。 能修建,则返回最小的距离和。如果无法修建,则返回 -1。
若范围限制在100*100以内的网格,如何计算出最小的距离和?
当平面网格非常大的情况下,如何避免不必要的计算?
Shopee物流会有很多个中转站。在选址的过程中,会选择离用户最近的地方建一个物流中转站。
假设给你一个二维平面网格,每个格子是房子则为1,或者是空地则为0。找到一个空地修建一个物流中转站,使得这个物流中转站到所有的房子的距离之和最小。 能修建,则返回最小的距离和。如果无法修建,则返回 -1。
若范围限制在100*100以内的网格,如何计算出最小的距离和?
当平面网格非常大的情况下,如何避免不必要的计算?
4
0 1 1 0
1 1 0 1
0 0 1 0
0 0 0 0
先输入方阵阶数,然后逐行输入房子和空地的数据,以空格分隔。
8
能修建,则返回最小的距离和。如果无法修建,则返回 -1。
4 0 1 1 0 1 1 0 1 0 0 1 0 0 0 0 0
8
4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
-1
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.ArrayList; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int[][] grid = new int[n][n]; int[][] onesCnt = new int[2][n]; // 第一行是每行1的个数,第二行是每列1的个数 ArrayList<int[]> startPoints = new ArrayList<>(); for(int i = 0; i < n; i++){ String[] row = br.readLine().split(" "); for(int j = 0; j < n; j++){ int val = Integer.parseInt(row[j]); if(val == 1){ onesCnt[0][i] ++; onesCnt[1][j] ++; }else{ startPoints.add(new int[]{i, j}); } } } // 没有空地直接返回-1 if(startPoints.isEmpty()){ System.out.println(-1); }else{ int minDis = Integer.MAX_VALUE; for(int[] point: startPoints){ // 以当前位置为中转站位置 int curDis = 0; for(int i = 0; i < n; i++){ curDis += Math.abs(i - point[0]) * onesCnt[0][i]; // 距离为abs(i-point[0])的点有onesCnt[0][i]个 curDis += Math.abs(i - point[1]) * onesCnt[1][i]; } minDis = Math.min(minDis, curDis); } System.out.println(minDis); } } }scala版
import scala.io.StdIn import scala.collection.mutable.ListBuffer object Main { def main(args: Array[String]): Unit = { val n = StdIn.readInt val freeSpace = ListBuffer[Array[Int]]() val onesCnt = Array.ofDim[Int](2, n) for(i <- 0 until n){ val row = StdIn.readLine.split(" ") for(j <- 0 until n){ if(row(j) == "1"){ onesCnt(0)(i) += 1 onesCnt(1)(j) += 1 }else freeSpace.append(Array[Int](i, j)) } } if(freeSpace.isEmpty){ println(-1) }else{ var minDis = Integer.MAX_VALUE for(pos: Array[Int] <- freeSpace){ var curDis = 0 for(i <- 0 until n) curDis += math.abs(i - pos(0)) * onesCnt(0)(i) + math.abs(i - pos(1)) * onesCnt(1)(i) minDis = math.min(minDis, curDis) } println(minDis) } } }
import java.util.*; public class Main{ public static void main(String[] strs){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = Integer.valueOf(sc.nextLine()); int[][] house = new int[n][n]; for(int i =0;i<n;i++){ String[] str = sc.nextLine().split(" "); for(int j=0;j<n;j++){ house[i][j] = Integer.valueOf(str[j]); } } //表示是不是全1,是的话flag为1,有0则为0 int flag = 1; int min = Integer.MAX_VALUE; int sum = 0; for(int i =0;i<n;i++){ for(int j =0;j<n;j++){ if(house[i][j]==1){ continue; }else { flag = 0; min = getDistance(min,house,i,j); } } } if(flag==1)min = -1; System.out.println(min); } } public static int getDistance(int min,int[][] house,int i,int j){ int sum = 0; int n = house[0].length; for(int k=0;k<n;k++){ for(int l =0;l<n;l++){ if(house[k][l]==0){ continue; }else{ if(k>i){sum+=(k-i);} else{sum+=(i-k);} if(l>j){sum+=(l-j);} else{sum+=(j-l);} } } } return sum<min?sum:min; } }暴力Java循环