谷歌foobar 4级与兔子一起运行

brccelvz  于 2021-08-20  发布在  Java
关注(0)|答案(0)|浏览(308)

我被困在foobar问题的一个测试用例上。
问题和我的代码如下
你和你获救的兔子囚犯需要尽快走出这个正在倒塌的空间站死亡陷阱!不幸的是,一些兔子由于长期监禁而变得虚弱,不能跑得很快。他们的朋友正试图帮助他们,但如果你也参与进来,这种逃跑会快得多。防御性舱壁门已经开始关闭,如果你不及时通过,你将被困住!你需要抓住尽可能多的兔子,在它们关上之前穿过舱壁。
从起点移动到所有兔子和舱壁所需的时间将以整数的平方矩阵形式给出。每一排都会告诉你到达起点所需的时间,第一只兔子,第二只兔子,…,最后一只兔子,然后依次到达舱壁。行的顺序遵循相同的模式(开始、每个兔子、隔板)。兔子可以跳到你的怀里,所以抓起它们是瞬间的,同时到达舱壁,因为它密封,仍然允许一个成功的,如果戏剧性的,逃脱(别担心,任何你没有捡到的兔子都可以和你一起逃走,因为它们不再需要携带你捡到的兔子了。)如果你愿意,你可以重游不同的地方,搬到舱壁并不意味着你必须立即离开——如果时间允许,你可以在舱壁上来回走动,捡起更多的兔子。
除了花时间在兔子之间旅行外,一些路径还与空间站的安全检查站相互作用,并将时间加回到时钟上。向时钟添加时间将延迟舱壁门的关闭,如果在舱壁门已经关闭后时间返回到0或正数,则会触发舱壁重新打开。因此,在一个圆圈中行走并不断获得时间是可能的:也就是说,每次穿过一条路径时,使用或增加的时间量是相同的。
写一个函数形式的答案(时间,时间限制)来计算你能捡到的最多的兔子以及它们是哪只兔子,同时在门永远关上之前仍然通过舱壁逃走。如果有多组大小相同的兔子,则按排序顺序返回具有最低囚犯ID(作为索引)的兔子集。兔子被表示为按囚犯id排序的列表,第一个兔子是0。最多有5个兔子,时间限制是一个非负整数,最多999。
例如,在[
[0,2,2,2,-1],#0=开始
[9,0,2,2,-1],#1=兔子0
[9,3,0,2,-1],#2=兔子1
[9,3,2,0,-1],#3=兔子2
[9,3,2,2,0]、#4=舱壁]和时间限制为1时,五个内部数组行分别指定起点、兔子0、兔子1、兔子2和舱壁门出口。您可以选择以下路径:
开始-结束增量时间状态-0-1舱壁初始打开0 4-1 2 4 2 0 2 4-1 1 4 3 2-1舱壁关闭3 4-1 0舱壁重新打开;你和兔子带着这个解决方案离开,你会带上兔子1和2。这是这个空间站走廊的最佳组合,所以答案是[1,2]。
测试用例输入:
(int)时间=[[0,1,1,1,1],[1,0,1,1,1],[1,1,0,1,1],[1,1,1,0,1],[1,1,1,1,0]](int)时间限制=3输出:
(整数列表)[0,1]输入:
(int)时间=[[0,2,2,1],[9,0,2,2,2,1],[9,3,0,2,1],[9,3,2,0,1],[9,3,2,2,0]。(int)时间限制=1输出:
(国际名单)[1,2]
在下面添加我的代码。

public class RunningWithBunnies {

    public static class FloydWarshall {

        private final Integer[][] allPairShortestPathMatrix;
        private final Integer[][] pathFinderMatrix;

        public FloydWarshall(final Integer[][] matrix) {

            if (matrix.length != matrix[0].length) {
                throw new IllegalArgumentException("Bad Adj Matrix Passed");
            }

            allPairShortestPathMatrix = new Integer[matrix.length][matrix[0].length];
            pathFinderMatrix = new Integer[matrix.length][matrix[0].length];
            for(int i = 0; i < matrix.length; i++) {
                for(int j = 0; j < matrix[i].length; j++) {
                    allPairShortestPathMatrix[i][j] = matrix[i][j];
                    if(matrix[i][j] != null) {
                        pathFinderMatrix[i][j] = j;
                    }
                }
            }
            findAllPairsShortestPath(matrix);
        }

        public int getShortestDistanceBetweenNodes(final int startNode, final int endNode) {
            return allPairShortestPathMatrix[startNode][endNode];
        }

        public List<Integer> findShortestPathBetweenNodes(final int startNode, final int endNode) {

            final List<Integer> path = new ArrayList<>();
            Integer currentNode = startNode;
            path.add(startNode);

            while (currentNode != endNode) {

                currentNode = pathFinderMatrix[currentNode][endNode];
                if (currentNode == null || allPairShortestPathMatrix[currentNode][currentNode] < 0) {
                    return Collections.emptyList();
                }
                path.add(currentNode);
            }

            return new ArrayList<>(path);
        }

        public boolean doesMatrixContainNegativeCycles() {

            for (int i = 0; i < allPairShortestPathMatrix.length; i++) {
                if (allPairShortestPathMatrix[i][i] < 0) {
                    return true;
                }
            }
            return false;
        }

        private void findAllPairsShortestPath(final Integer[][] matrix) {

            for(int k = 0; k < matrix.length; k++) {
                for(int i = 0; i < matrix.length; i++) {
                    for(int j = 0; j < matrix[i].length; j++) {

                        final Integer directPathCost = allPairShortestPathMatrix[i][j];
                        final Integer indirectPathToIntermediateCost = allPairShortestPathMatrix[i][k];
                        final Integer indirectPathFromIntermediateCost = allPairShortestPathMatrix[k][j];

                        if (indirectPathToIntermediateCost != null && indirectPathFromIntermediateCost != null) {
                            if (directPathCost == null ||
                                (directPathCost > indirectPathToIntermediateCost + indirectPathFromIntermediateCost)) {
                                allPairShortestPathMatrix[i][j] = allPairShortestPathMatrix[i][k] + allPairShortestPathMatrix[k][j];
                                pathFinderMatrix[i][j] = pathFinderMatrix[i][k];
                            }
                        }
                    }
                }
            }
        }
    }

    public static int[] solution(int[][] times, int times_limit) {

        final Integer[][] matrix = new Integer[times.length][times[0].length];
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                matrix[i][j] = times[i][j];
            }
        }
        final FloydWarshall floydWarshall = new FloydWarshall(matrix);

        final Set<Integer> bunniesLeft = IntStream
            .range(1, matrix.length - 1)
            .boxed()
            .collect(Collectors.toSet());

        if (floydWarshall.doesMatrixContainNegativeCycles()) {

            return bunniesLeft
                .stream()
                .mapToInt(bunny -> bunny - 1)
                .toArray();
        }

        final List<Integer[]> path = new ArrayList<>();

        int currentPos = 0;
        int pathCost = 0;
        while (!bunniesLeft.isEmpty()) {

            int nearestBunnyPathDuration = Integer.MAX_VALUE;
            int nearestBunny = -1;
            for (int bunnyPosition : bunniesLeft) {

                if (bunnyPosition != currentPos
                    && bunniesLeft.contains(bunnyPosition)
                    && floydWarshall.getShortestDistanceBetweenNodes(currentPos, bunnyPosition) < nearestBunnyPathDuration) {

                    nearestBunnyPathDuration = floydWarshall.getShortestDistanceBetweenNodes(currentPos, bunnyPosition);
                    nearestBunny = bunnyPosition;
                }
            }

            if (nearestBunny == -1) {
                break;
            }

            final List<Integer> subPath =
                floydWarshall
                    .findShortestPathBetweenNodes(currentPos, nearestBunny)
                    .stream()
                    .filter(bunniesLeft::contains)
                    .collect(Collectors.toList());

            currentPos = nearestBunny;

            for (int subPathNode : subPath) {

                path.add(new Integer[]{
                    subPathNode,
                    path.isEmpty()
                        ? floydWarshall.getShortestDistanceBetweenNodes(0, subPathNode)
                        : pathCost + floydWarshall.getShortestDistanceBetweenNodes(path.get(path.size() - 1)[0], subPathNode)
                });
                bunniesLeft.remove(subPathNode);
                pathCost = path.get(path.size() - 1)[1];
            }
        }

        path.removeIf(pathNode ->
            pathNode[1] + floydWarshall.getShortestDistanceBetweenNodes(pathNode[0], matrix.length - 1) > times_limit
        );

        if (path.isEmpty()) {
            return new int[]{};
        }

        return path
            .stream()
            .mapToInt(node->node[0] - 1)
            .sorted()
            .toArray();
    }
}

只有测试用例8失败。我在stack overflow中见过其他解决方案,但没有一个采用这种方法。如果您能给我指点一下,我将不胜感激。
谢谢

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题