如何通过一系列地图释放条件来计算当前应该打开哪张地图?

问题描述 投票:0回答:1

给定四张地图的开放时间和最后一次(单位为天):

NAME | AVAILABLE_TIME | LAST_TIME
mapA | 8              | 3
mapB | 11             | 3
mapC | 15             | 3
mapD | 35             | 3

这意味着:

The 1th day is server open day. 
On 8th day, the mapA becomes available; 
On 11th day, the mapB becomes available;
On 14th day, the mapC becomes  available;
On 35th day , the mapD becomes available;

如果打开任何地图,它将持续

LAST_TIME
天。当打开的地图完成后,00:00 AM,系统会检查下一个地图是否存在且可用,如果存在,系统将关闭当前地图并打开下一个地图,否则系统将打开可用的地图从一开始。

例如,从第1天到第7天,没有地图可用,因此没有地图可打开。

第8天,mapA可用,因此将打开并持续3天。

第11天,系统将关闭mapA,发现下一个mapB现在可用,因此将打开mapB。地图B将持续3天。

第14天,mapB关闭,系统发现下一个mapC不可用,于是从头开始打开可用的地图,也就是这一天打开mapA。

第17天,系统关闭mapA并打开mapB。第20天,mapC开放。

我不知道如何将整个过程转化为一个方法,通过输入天数并获取当天应该打开的地图。当我尝试编码时,我的头脑总是感到困惑,尤其是打开地图的循环。有人可以教我如何编写这个逻辑吗(如果你写一些代码,任何语言或伪代码都可以),或者也欢迎一点点思考。

algorithm cycle
1个回答
0
投票

经过一番思考,我找到了解决办法:

public class Application {
    public static void main(String[] args) {
        int[] openArr = {8, 11, 15, 35};
        int[] keepArr = {3, 3, 3, 3};
        for (int i = 1; i < 50; i++) {
            System.out.println(i + ": " + getOpenMapIndex(i, openArr, keepArr));
        }
    }

    private static int getOpenMapIndex(int day, int[] openArr, int[] keepArr) {
        int begin = openArr[0];
        int end = openArr[openArr.length - 1];
        if (day < begin) {
            return -1;
        }

        int index = 0;
        int curDay = begin - 1;
        int lastDay = keepArr[index];
        while (curDay != day) {
            curDay++;
            lastDay--;

            if (lastDay == -1) {
                int avaIndex = findFirstLess(openArr, curDay);
                int[] avaArr = Arrays.stream(openArr).limit(avaIndex + 1).toArray();

                if (index + 1 <= avaArr.length - 1) {
                    index++;
                } else {
                    index = 0;
                }
                lastDay = keepArr[index] - 1;

                if (index == 0 && curDay >= end) {
                    int diff = day - curDay;
                    int turn = diff % Arrays.stream(keepArr).sum();
                    int sum = 0;
                    for (int i = 0; i < keepArr.length; i++) {
                        sum += keepArr[i];
                        if (turn < sum) {
                            return i;
                        }
                    }
                }
            }
        }
        return index;
    }


    public static int findFirstLess(int[] sortedArr, int target) {
        if (sortedArr == null || sortedArr.length == 0) {
            return -1;
        }

        if (sortedArr[0] > target) {
            return -1;
        }

        int left = 0, right = sortedArr.length - 1;
        int index = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (sortedArr[mid] <= target) {
                index = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return index;
    }


}

© www.soinside.com 2019 - 2024. All rights reserved.