最小距离和

题目描述

终端公司的零售店需要定期去仓库提取货物,假设零售店和仓库在一个矩阵上:相邻点的距离为 1 ;只能通过上下左右走动。
矩阵元素的值仅为三种:0,表示仓库; -1,表示障碍; 1,表示零售店。 注:障碍无法通过,其它可以通过。

为了将取货效率最大化,需要计算每个零售店走到最近仓库的最小距离,并输出这些最小距离的和:

无法到达仓库的零售店,不参与距离和的计算;
没有零售店或者没有仓库的话,返回0;

解答要求

时间限制:3000ms, 内存限制:256MB

输入

第一行为两个数字 m 和 n,表示数组的行数和列数,m和n的范围均为 [1,300) 。
接下来的 m 行表示一个 m*n 的数组,每行的元素间以空格分割。

输出

一个整数,表示所计算的最小距离和。

样例

输入样例 1

3 3
1 -1 0
0 1 1
1 -1 1

输出样例 1

6

提示样例 1

如下图所示,共有5个零售店(绿色),2个仓库(红色),2个障碍(白色),零售店上标注的数字表示到最近仓库的最小距离:

位置[2][2]的零售店,距离[0][2]的仓库为 2,距离[1][0]的仓库为 3,因此到最近仓库的最小距离为 2 ; 其余零售店到最近仓库的最小距离都为 1。所以,所有零售店到仓库的最小距离和为 1 + 1 + 1 + 1 + 2 = 6 。

输入样例 2

2 3
0 -1 1
1 -1 1

输出样例 2

1

提示样例 2

位置[0][2]和[1][2]的零售店无法到达唯一的仓库[0][0],只有[1][0]的零售店可以到达,且最近距离为 1 。

Java算法源码

import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class MinDistanceSum {
    // 待实现函数,在此函数中填入答题代码
    static int[][] distanceMap;
    private static int nearestWareHouse(int[][] grid) {
        distanceMap = new int[grid.length][grid[0].length]; // 最大为300
        // 初始化 distanceMap
        for (int row = 0; row < grid.length; row++) {
            for (int col = 0; col < grid[0].length; col++) {
                // 设置为最大可能距离
                distanceMap[row][col] = grid.length + grid[0].length;
            }
        }
        // 从仓库向外寻找商店,并计算距离。
        for (int row = 0; row < grid.length; row++) {
            for (int col = 0; col < grid[0].length; col++) {
                // 仓库位置
                if (grid[row][col] == 0) {
                    dfs(grid, row, col, 0);
                }
            }
        }
        // 求总路程距离
        int totalDistance = 0;
        for (int row = 0; row < grid.length; row++) {
            for (int col = 0; col < grid[0].length; col++) {
                // 跳过无法达到,和障碍物的地址。
                if (distanceMap[row][col] == grid.length + grid[0].length) {
                    continue;
                }
                totalDistance += distanceMap[row][col];
            }
        }
        return totalDistance;
    }
    // 深度优先遍历递归实现
    static void dfs(int[][] grid, int row, int col, int distance) {
        // 超出边界
        if (row >= grid.length || row < 0 || col >= grid[0].length || col < 0 || distance >= (grid.length + grid[0].length)) {
            return;
        }
        // 遇到障碍物,此路不通。
        if (grid[row][col] == -1) {
            return;
        }
        // 已经有最短路径,更长路线不作考虑
        if (distance >= distanceMap[row][col]) {
            return;
        }
        // 记录距离
        distanceMap[row][col] = distance;
        distance++;
        // 继续其他路径
        dfs(grid, row + 1, col, distance); // up
        dfs(grid, row - 1, col, distance); // down
        dfs(grid, row, col - 1, distance); // left
        dfs(grid, row, col + 1, distance); // right
    }
    
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in, StandardCharsets.UTF_8.name());
        int rows = cin.nextInt();
        int cows = cin.nextInt();
        int[][] grid = new int[rows][cows];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cows; j++) {
                grid[i][j] = cin.nextInt();
            }
        }
        System.out.println(nearestWareHouse(grid));

        cin.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软软的铲屎官

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值