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循环