简体   繁体   English

矩阵中最短距离的最大值

[英]Maximal value among shortest distances in a matrix

I am trying to solve the following problem and have not been able to develop an algorithm or approach.我正在尝试解决以下问题,但无法开发算法或方法。 I have researched for a few hours and tried to map the problem to "Shortest Path" graph/matrix problem or dynamic programming problems but have been unsuccessful in it.我研究了几个小时并试图将问题映射到“最短路径”图/矩阵问题或动态规划问题,但没有成功。

Given a grid with w as width, h as height.给定一个宽度为 w、高度为 h 的网格。 Each cell of the grid represents a potential building lot and we will be adding "n" buildings inside this grid.网格的每个单元格代表一个潜在的建筑物,我们将在此网格内添加“n”个建筑物。 The goal is for the furthest of all lots to be as near as possible to a building.目标是使所有地块中最远的地块尽可能靠近建筑物。 Given an input n, which is the number of buildings to be placed in the lot, determine the building placement to minimize the distance the most distant empty lot is from the building.给定输入 n,即要放置在地块中的建筑物数量,确定建筑物放置以最小化最远的空地块与建筑物的距离。 Movement is restricted to horizontal and vertical ie diagonal movement is not required.运动仅限于水平和垂直,即不需要对角运动。

For example, w=4, h=4 and n=3 .例如, w=4, h=4 and n=3 An optimal grid placement sets any lot within two unit distance of the building.最佳的网格放置将任何地段设置在建筑物的两个单位距离内。 The answer for this case is 2.这个案例的答案是2。

"0" indicates optimal building placement and in this case the maximal value of all shortest distances to the closest building for each cell is "2". “0”表示最佳建筑物放置,在这种情况下,每个单元格到最近建筑物的所有最短距离的最大值为“2”。

1 0 1 2
2 1 2 1
1 0 1 0
2 1 2 1

The above represents one optimal solution, there could be more like the above array rotated as an example.以上代表了一种最优解,可能还有更多像上面旋转的阵列的例子。 The above is an optimal solution because out of the 3 buildings (n=3), one building was placed at index (0,1), second was placed at (2,1) and third was placed at (2,3).以上是最佳解决方案,因为在 3 个建筑物 (n=3) 中,一个建筑物位于索引 (0,1),第二个位于 (2,1),第三个位于 (2,3)。 The surrounding horizontal and vertical distance is shown as 1 and 2 by adding 1 each time we move horizontally and/or vertically.每次我们水平和/或垂直移动时,周围的水平和垂直距离都显示为 1 和 2。 Note again that diagonal movement is not allowed:再次注意,不允许对角移动:

1 ← 0 → 1 → 2
    ↓
2 ← 1 → 2 ← 1
    ↑       ↑
1 ← 0 → 1 ← 0
    ↓       ↓
2 ← 1 → 2 ← 1

Other examples:其他例子:

Example 1)示例 1)

w=3, h=3, n=2

Two buildings (zeros) have to be optimally placed.必须最佳放置两座建筑物(零点)。 One of the optimal plan for this case is:这种情况下的最佳计划之一是:

01
11
10

0 → 1
↓
1   1
    ↑  
1 ← 0

Answer: 1

As an example, the following plan will not be optimal in this case because it has the maximal smallest distance as 2 instead of 1. So, placing 0 greedily at index (1,0) does not work even though the 0 covers three "1" positions in this case instead of two as in above optimal scenario.例如,下面的计划在这种情况下不是最优的,因为它的最大最小距离为 2 而不是 1。因此,即使 0 覆盖三个“1”,将 0 贪婪地放置在索引 (1,0) 上也不起作用" 在这种情况下的位置,而不是上述最佳方案中的两个位置。

1 → 2
↑
0 → 1
↓   ↑   
1 ← 0

Example 2)例 2)

w=5, h=1, n=1

One building (zeros) has to be optimally placed.必须最佳放置一栋建筑物(零)。 One of the optimal plan:最优方案之一:

2 ← 1 ← 0 → 1 → 2

Answer: 2

Example of a non-optimal plan in the above scenario:上述场景中的非最优计划示例:

3 ← 2 ← 1 ← 0 → 1

The below function should be completed:应完成以下功能:

int findMinDist(int w, int h, int n)
{

}

Constraints:约束:

1<=w,h
w*h <=28
1<=n<=5
n<=w*h

I haven't been able to write any code because honestly I haven't been able to deduce the solution.我一直无法编写任何代码,因为老实说我无法推断出解决方案。

If the two given points are fixed points in a 2d matrix, I can find the distance or shortest distance between the two.如果给定的两个点是二维矩阵中的固定点,我可以找到两者之间的距离或最短距离。 But, in this case, I don't know where the two points will be?但是,在这种情况下,我不知道这两个点会在哪里? There can be many optimal solutions and placing combinations of 0 at each place and finding the farthest distance is not possible and will not be feasible.可以有很多最优解,在每个地方放置0的组合,找到最远的距离是不可能的,也不可行。 I have tried to place them at positions which yield maximum amount of 1 (like middle or w/2) but that does not seem to work too.我试图将它们放在最大数量为 1 的位置(如中间或 w/2),但这似乎也不起作用。 Could an existing algorithm be applied to this problem?可以将现有算法应用于此问题吗?

As per the given constraint, the matrix size ( w*h ) cannot exceed 28 which is fairly a small number.根据给定的约束,矩阵大小 ( w*h ) 不能超过 28,这是一个相当小的数字。 Also, the maximum possible value for n is 5. From little knowledge of combinatorics, we know that there are 28 C 5 ways of selecting 5 lots from the given grid at the worst case.此外, n的最大可能值是 5。根据对组合学的一些了解,我们知道在最坏的情况下,有28 C 5种方法可以从给定的网格中选择 5 个批次。 The figure evaluates to 98280 which is a sufficiently a small space to search over with memoization.该数字评估为 98280,这是一个足够小的空间,可以通过记忆进行搜索。 Since the maximum value for w*h is 28, we can represent the entire grid in a single integer bit-mask which along with the number of building lot left to be set up will form the states of our DP.由于w*h的最大值是 28,我们可以用一个整数位掩码来表示整个网格,它与剩余的建筑地块数量将形成我们 DP 的状态。 To calculate the farthest leftover lot for the end state, we make use of a Breadth First Search (BFS) by initializing the queue with all points where we've set up a building.为了计算最终状态的最远剩余地段,我们使用广度优先搜索 (BFS),通过使用我们已经建立建筑物的所有点初始化队列。 Sharing the code for the same which runs sufficiently fast enough https://ideone.com/ix1nh8共享运行速度足够快的相同代码https://ideone.com/ix1nh8

int W, H, N;

int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, -1, 1};

int calc(int i, int j) {
    if(W <= H)
        return  i + W * j;
    return H * i + j;
}

bool get(int bitmask, int i, int j) {
    return (bitmask&(1<<calc(i,j)));
}

int bfs(int bitmask) {
    int dist[W][H];
    memset(dist, -1, sizeof dist);

    int maxDist = 0;
    queue<pair<int,int>> Q;

    for(int i = 0; i < W; i++)
        for(int j = 0; j < H; j++)
            if(get(bitmask, i, j)) {
                dist[i][j] = 0;
                Q.push({i, j});
            }
    assert(Q.size() == N);

    while(!Q.empty()) {
        int x = Q.front().first;
        int y = Q.front().second;
        maxDist = max(maxDist, dist[x][y]);
        Q.pop();

        for(int d = 0; d < 4; d++) {
            int newx = x + dx[d];
            int newy = y + dy[d];

            if(newx >= W || newy >= H || newx < 0 || newy < 0)
                continue;
            if(dist[newx][newy] == -1) {
                dist[newx][newy] = dist[x][y] + 1;
                Q.push({newx, newy});
            }
        }
    }
    return maxDist;
}

map<pair<int,int>, int> dp;

int solve(int bitmask, int left) {
    if(left == 0) {
        return bfs(bitmask);
    }
    if(dp.find({bitmask, left}) != dp.end()) {
        return dp[{bitmask, left}];
    }
    int minDistance = INT_MAX;
    for(int i = 0; i < W; i++)
        for(int j = 0; j < H; j++)
            if(!get(bitmask, i, j)) {
                int val = solve((bitmask|(1<<calc(i, j))), left-1);
                minDistance = min(minDistance, val);
            }
    return dp[{bitmask, left}] = minDistance;
}

Java Solution without bitmask and need for memoization by passing the positions to the recursive calls没有位掩码且需要通过将位置传递给递归调用来记忆的 Java 解决方案

class MaximumShortestDist
{
    static int[] dx = new int[]{1, -1, 0, 0};
    static int[] dy = new int[]{0, 0, -1, 1};

    public static void main(String[] args) {
        System.out.println(findMinDist(14,2,5));
    }

    static int findMinDist(int w, int h, int n)
    {

        int[][] grid = new int[w][h];
        for(int i=0;i<w;i++)
            Arrays.fill(grid[i],-1);
        return solve(n,w,h,0,0,grid);
    }

    static int bfs(int W, int H, int[][] grid) {

        int[][] dist = new int[W][H];
        for(int i=0;i<W;i++)
            for(int j=0;j<H;j++)
                dist[i][j] = grid[i][j];

        int maxDist = 0;
        Queue<Location> Q = new LinkedList<>();
        for(int i = 0; i < W; i++)
            for(int j = 0; j < H; j++)
                if(dist[i][j] == 0){
                    Q.add(new Location(i,j));
                }

        while(!Q.isEmpty()) {
            int x = Q.peek().first;
            int y = Q.peek().second;
            maxDist = Math.max(maxDist, dist[x][y]);
            Q.poll();

            for(int d = 0; d < 4; d++) {
                int newx = x + dx[d];
                int newy = y + dy[d];

                if(newx >= W || newy >= H || newx < 0 || newy < 0)
                    continue;
                if(dist[newx][newy] == -1) {
                    dist[newx][newy] = dist[x][y] + 1;
                    Q.add(new Location(newx, newy));
                }
            }
        }
        return maxDist;
    }

    static int solve(int left, int W, int H, int row, int col,int[][] grid) {
        if(left == 0) {
            return bfs(W,H,grid);
        }
        int r = row,c=col;
        if(col >= H) {
            r += col/H;
            c = col%H;
        }
        int minDistance = Integer.MAX_VALUE;
        for(int i=r;i<W;i++){
            for(int j=c;j<H;j++) {
                //Mark Building locations in the recursive call.
                grid[i][j] = 0;
                int val = solve(left-1, W, H,i,j+1,grid);
                minDistance = Math.min(minDistance, val);
                // Remove the building
                grid[i][j] = -1;
            }
        }
        return minDistance;
    }
}


class Location {
    int first;
    int second;
    Location(int x, int y) {
        first = x;
        second = y;
    }
}

Look at this simple python program.看看这个简单的python程序。

  1. It finds all possible permutations of where the offices may lie它找到了办公室所在位置的所有可能排列
  2. Then it finds the maximum distance to a cell from the closest office [use BFS]然后它找到离最近办公室的单元格的最大距离[使用 BFS]
  3. Take the minimum distance of all such maximums取所有这些最大值的最小距离
def findMinDistance(w, h, n):
    def maxDist(w,h,p):
        arr = [[-1]*h for i in range(w)]
        q = collections.deque()
        for x in p:
            r,c = x//h, x%h
            arr[r][c] = 0
            q.append((r,c,0))

        maxd = -1
        while len(q):
            x,y,d = q.popleft()
            maxd = max(maxd, d)
            if 0 <= x+1 < w and arr[x+1][y] == -1:
                arr[x+1][y] = d+1
                q.append((x+1,y,d+1))
            if 0 <= x-1 < w and arr[x-1][y] == -1:
                arr[x-1][y] = d+1
                q.append((x-1,y,d+1))
            if 0 <= y+1 < h and arr[x][y+1] == -1:
                arr[x][y+1] = d+1
                q.append((x,y+1,d+1))
            if 0 <= y-1 < h and arr[x][y-1] == -1:
                arr[x][y-1] = d+1
                q.append((x,y-1,d+1))

        return maxd

    ans = 100000
    pos = [i for i in range(w*h)]
    for p in list(itertools.combinations(pos, n)):
        ans = min(ans, maxDist(w,h,p))
    return ans

The Java code for this without the bitwise operations.没有按位运算的 Java 代码。

import javafx.util.Pair;
import java.util.*;

class Office_N {
    // W for width, H for height, N for no of offices to build
    int W, H, N;

    // dx and dy value together gives (x,y)
    // which helps to move in 4 adjacent cells
    // Right (1,0)
    // Left (-1,0)
    // Down (0,1)
    // Up (0,-1)
    int[] dx = {1, -1, 0, 0};
    int[] dy = {0, 0, 1, -1};
    Map<String, Integer> dp = new HashMap<>();

    int[][] grid;

    // Constructor will set the values and clear the hashmap.
    public Office_N(int w, int h, int n) {
        W = w;
        H = h;
        N = n;
        dp.clear();
        grid = new int[W][H];

        for (int[] r : grid) {
            Arrays.fill(r, 0);
        }
    }

    // We convert the 2D array of W*H into 1D array in Row Order (if square matrix or Width is less),
    // or Column Wise (if Height is less)
    // BitMask holds the bits 0 empty spots, and 1 for where offices are present
    // Left means how many offices are still left to be built
    public int solve(int[][] grid, int left) {

        // If no more offices are left to be built, get the maximum distance for this scenario
        if (left == 0) {
            return bfs(grid);
        }

        StringBuilder k = new StringBuilder();

        for (int i = 0; i < W; i++) {
            for (int j = 0; j < H; j++) {
                if (grid[i][j] == 1) {
                    k.append(i + ":" + j + "::");
                }
            }
        }

        k.append("#" + left);
        // if the current scenario along with offices left are already processed, return the result
        String key = k.toString();
        if (dp.containsKey(key)) {
            return dp.get(key);
        }

        int[][] gridtemp = new int[W][H];
        for (int i = 0; i < W; i++) {
            for (int j = 0; j < H; j++) {
                gridtemp[i][j] = grid[i][j];
            }
        }

        //  We are trying every possible scenario to build offices in the given grid
        int minDist = Integer.MAX_VALUE;
        for (int i = 0; i < W; i++) {
            for (int j = 0; j < H; j++) {
                // If no office present in (i,j)th location, put one office there and check the minimum distance for that scenario
                if (gridtemp[i][j] == 0) {
                    gridtemp[i][j] = 1;
                    int val = solve(gridtemp, left - 1);
                    minDist = Math.min(minDist, val);
                    gridtemp[i][j] = 0;
                }
            }
        }

        // Store the min distance possible for the current scenario
        dp.put(key, minDist);
        return minDist;
    }

    // This function gives the maximum distance from all the empty spots to the offices for a given case of scenario
    private int bfs(int[][] grid) {
        // get a distance matrix with initial values as -1
        int[][] dist = new int[W][H];
        for (int[] row : dist)
            Arrays.fill(row, -1);

        int maxDist = 0;
        // Queue for processing the cells in Bredth-First-Search order.
        Queue<Pair<Integer, Integer>> Q = new LinkedList<>();

        // if office is present at (i,j)th location, the distance is 0, and put the (i,j) pair in Queue
        for (int i = 0; i < W; i++) {
            for (int j = 0; j < H; j++) {
                if (grid[i][j] == 1) {
                    dist[i][j] = 0;
                    Q.add(new Pair<>(i, j));
                }
            }
        }


        while (!Q.isEmpty()) {
            Pair<Integer, Integer> kv = Q.poll();
            int x = kv.getKey();
            int y = kv.getValue();

            // Get maximum distance for (i,j)th location
            maxDist = Math.max(maxDist, dist[x][y]);

            // Process all adjacent cells
            for (int d = 0; d < dx.length; d++) {
                int xNew = x + dx[d];
                int yNew = y + dy[d];

                // if the adjacent cell is within grid boundary, and is not yet processed,
                // set the max dist of he adjacent cell 1 more than the (i,j)th cell
                // add the adjacent cell to queue
                if (xNew >= 0 && xNew < W && yNew >= 0 && yNew < H && dist[xNew][yNew] == -1) {
                    dist[xNew][yNew] = dist[x][y] + 1;
                    Q.add(new Pair<>(xNew, yNew));
                }
            }
        }

        return maxDist;
    }

    public static void main(String[] args) {
        Office_N ofc = new Office_N(4, 4, 3);
        int res = ofc.solve(ofc.grid, ofc.N);
        System.out.println(res);
    }
}

I use math method to achieve the solution.我使用数学方法来实现解决方案。

The shortest distance comes from the optimal occupied subarea in the grid.最短距离来自网格中最佳占用分区 It means that the max value of each subarea's difference is 1 .这意味着每个分区的差异的最大值为1 Take w=4, h=4 and n=3 as example.w=4, h=4 and n=3为例。 In this grid, there are 16 nodes inside.在这个网格中,内部有 16 个节点。 For each occupied area of building, we can calculate by w*h/n = 16/3 = 5.33... .对于建筑物的每个占用面积,我们可以通过w*h/n = 16/3 = 5.33... It means that the max number of nodes in the area is the ceiling number A = Math.ceil(w*h/n) = 6 .这意味着该区域的最大节点数是天花板数A = Math.ceil(w*h/n) = 6

From above calculation, there is only one node in each subarea , so that we could put this building at the center in assumption.由上面的计算,每个分区只有一个节点,所以我们可以假设这个建筑物位于中心。 Then we could calculate that the longest distance from the building to the edge would be Math.sqrt(A) = 2.45 .然后我们可以计算出从建筑物到边缘的最长距离是Math.sqrt(A) = 2.45 The ceiling number is 3 .上限数为3 Since it is zero-based, we could minus 1 to get 2 .由于它是从零开始的,我们可以减去 1 得到2

Special Case - width or height is 1 :特殊情况- 宽度或高度为1

We could use the other math calculation which is much simpler than above to solve.我们可以使用比上面简单得多的其他数学计算来解决。

Here is my C++ version of solution.这是我的 C++ 版本的解决方案。 I have tested all the test cases in Build Offices Google Doc and it works.我已经测试了Build Offices Google Doc 中的所有测试用例,并且可以正常工作。 The challenge seems very terrifying;挑战似乎非常可怕; however, it would change to a very simple problem if you found description of w*h <= 28 in problem.然而,如果你发现w*h <= 28描述有问题,它就会变成一个非常简单的问题。 Therefore, I just need to use depth-first search to list all the cases of 0 and breadth-first search to find the shortest path visiting the whole map, Done:) You can find more details in comments, Good luck.因此,我只需要使用深度优先搜索列出所有0和广度优先搜索的情况来找到访问整个地图的最短路径,完成:)你可以在评论中找到更多细节,祝你好运。

#include <bits/stdc++.h>
using namespace std;

int w, h, n;
vector<int> dirx = {0, 0, 1, -1};
vector<int> diry = {1, -1, 0, 0};
int maxdistance = INT_MAX;

// help convert (x, y) to decimal-based position
int calc(int x, int y) {
    return (w * x) + y;
}

// check whether out of bound and visited before in bfs
bool check_valid(int x, int y, unordered_set<int> visited) {
    if(x < 0 || x >= h)
        return false;
    if(y < 0 || y >= w)
        return false;
    if(visited.count(calc(x, y)))
        return false;
    return true;
}

// level-ordered bfs and each time find the longest path on map
int bfs(vector<vector<int>> map,
        vector<pair<int, int>> start_point) {
    int local_max = 0;
    queue<pair<int, int>> q;
    unordered_set<int> visited;

    for(auto s : start_point) {
        q.push(s);
        visited.insert(calc(s.first, s.second));
    }

    int dist = 0;
    while(!q.empty()) {
        int sz = q.size();
        dist++;
        for(int i = 0; i < sz; i++) {
            pair<int, int> head = q.front();
            q.pop();
            for(int i = 0; i < 4; i++) {
                pair<int, int> neighbor = make_pair(head.first + dirx[i], head.second + diry[i]);
                if(check_valid(neighbor.first, neighbor.second, visited)) {
                    map[neighbor.first][neighbor.second] = dist;
                    visited.insert(calc(neighbor.first, neighbor.second));
                    q.push(neighbor);
                }
            }
        }
    }

    // after visiting the whole map
    // find the maxdistance
    for(int i = 0; i < h; i++) {
        for(int j = 0; j < w; j++) {
            if(map[i][j] > local_max)
                local_max = map[i][j];
        }
    }

    return local_max;
}

// list all the cases for starting point: 0
// in fact, not all the cases
// I considered optimal start point would show up in each distance of (w*h/n)
void dfs(vector<vector<int>> map,
        int d,
        int n_,
        int n, 
        vector<pair<int, int>> start_point) {
    if(n_ == n) {
        // cout << "Map: " << '\n';
        /**
        for(int i = 0; i < map.size(); i++) {
            for(int j = 0; j < map[i].size(); j++) {
                cout << map[i][j] << ' ';
            }
            cout << '\n';
        }
        cout << "distance?: ";**/
        if(bfs(map, start_point) < maxdistance) {
            maxdistance = bfs(map, start_point);
            cout << maxdistance << '\n';
        }
        return;
    }

    for(int i = 0; i < d; ++i) {
        int pos = n_ * d + i;
        map[pos / w][pos % w] = 0;
        start_point[n_].first = pos / w;
        start_point[n_].second = pos % w;
        dfs(map, d, n_ + 1, n, start_point);
        map[pos / w][pos % w] = INT_MAX;
        start_point[n_].first = -1;
        start_point[n_].second = -1;
    }
}

int main() {
    cin >> w >> h >> n;
    int d = (w*h)/n;   // build one office in each d distance
    vector<vector<int>> map(h, vector<int>(w, INT_MAX));
    vector<pair<int, int>> start_point(n, make_pair(-1, -1));
    dfs(map, d, 0, n, start_point);
    cout << "Max distance of one of optimal solution is: " << maxdistance << '\n';

    return 0;
}

I tried solving this question using python.我尝试使用 python 解决这个问题。 The core of the answer lies in my step function, which gets all possible position of the N buildings in a W x H grid and gives the result as a list.答案的核心在于我的 step 函数,它获取 W x H 网格中 N 建筑物的所有可能位置,并将结果作为列表给出。 Each position in the list is the location at W*i + H. That's the positions in a 2x2 are treated as 0, 1, 2, 3.列表中的每个位置都是 W*i + H 处的位置。 即 2x2 中的位置被视为 0、1、2、3。



# generator function to give each building position 
# in a W x H grid
def step(W, H, N):
    dim = W * H
    slots = [n for n in range(N)]
    slots_temp = list(slots)
    persist = list(slots)
    last = [dim - n for n in slots]
    last = last[::-1]
    while slots != [0] * N:
        yield slots
        for i in range(len(slots)-1,-1,-1):
            slots[i]+=1
            if slots[i] >= last[i] :
                slots[i] = 0
            else:
                while i < len(slots)-1:
                    slots[i+1] = slots[i] + 1
                    i+=1
                break

# converts a ixj to a step
# assumes W <= H
def get_step(i, j, W , H):
    return (i * W) + j

# does bfs from each building position
# and gets the maximum distance 
def bfs(step,W,H):
    dist = [[-1]*H for i in range(W)]
    queue = []
    dx = [1,-1,0,0]
    dy = [0,0,1,-1]
    for i in range(W):
        for j in range(H):
            step_val = get_step(i, j, W, H)
            if step_val in step:
                dist[i][j] = 0
                queue.append((i,j))
    max_val = 0
    while len(queue) != 0:
        i,j = queue.pop(0)
        max_val = max(max_val, dist[i][j])
        for _dx,_dy in zip(dx,dy):
            new_i,new_j = i + _dx, j + _dy
            if new_i < 0 or new_i >= W or new_j <0 or new_j >= H:
                continue
            if dist[new_i][new_j] == -1:
                dist[new_i][new_j] = dist[i][j] + 1
                queue.append((new_i,new_j))
    return max_val


# calls each posible position of the building
# and computes the minimum distance of all
def main(W, H, N ): 
    min_val = float('inf')
    if W > H:
        W, H = H, W
    s = step(W, H, N)
    for slot in s:
        b = bfs(slot, W, H)
        min_val = min(min_val, b)
    return min_val



main(4, 4, 2)

The Ruby code for this用于此的 Ruby 代码

class MaximumShortestDist
  def findMinDist(w, h, n)
  grid = Array.new(w){Array.new(h)}
  for i in 0...w do
      grid[i].fill(-1)
  end

  solve(n,w,h,0,0,grid);
end

def bfs(ww, hh, grid)
        dx = [1, -1, 0, 0];
dy = [0, 0, -1, 1];
    dist = Array.new(ww){Array.new(hh)};

    for i in 0...ww do
        for j in 0...hh do
            dist[i][j] = grid[i][j];
          end
        end

    maxDist = 0;

    qu = Array.new

    for i in 0...ww do
      for j in 0...hh do
          if dist[i][j] == 0
             qu.push(Location.new(i,j));
          end
      end
    end

    while !qu.empty?
        x = qu.first.first;
        y = qu.first.second;
        maxDist = [maxDist, dist[x][y]].max;
        qu.shift;

        for d in 0...4  do
            newx = x + dx[d];
            newy = y + dy[d];

            next if newx >= ww || newy >= hh || newx < 0 || newy < 0


            if dist[newx][newy] == -1
                dist[newx][newy] = dist[x][y] + 1;
                qu.push(Location.new(newx, newy));
            end
        end
    end

    return maxDist;
end

def solve(left, ww, hh, row,  col, grid)
    return bfs(ww,hh,grid) if left == 0

    r = row
    c=col

    if col >= hh
        r += col/hh;
        c = col%hh;
    end

    minDistance = 999;
    for i in r...ww do
        for j in c...hh  do
            grid[i][j] = 0;
            val = solve(left-1, ww, hh,i,j+1,grid);
            minDistance = [minDistance, val].min;
            grid[i][j] = -1;
        end
    end
    return minDistance;
  end
end


class Location
   attr_reader :first, :second
  def initialize(x, y)
    @first = x;
    @second = y;
  end
end

puts MaximumShortestDist.new.findMinDist(2,3,2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM