小便池计算坑位问题

263 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

image.png

众所周知,男生小便池有个不成文的规定,若是A站在0号位,那么B在只有A时会选择站在A的最远端,依照这个规律,男生的小便池利用率的上限也就二分之一了(也许,可能你是个狼人,站在A的旁边,并且还转头和A聊天)。

我们可以借此场景,很应景的将其抽象做为一道题目。

描述

那么,我们肯定希望离得远一点更好啊(也许其他人不这样想,只是我社恐罢了QAQ),那么,假设在厕所里,一排有 N 个坑位,分别编号为 0, 1, 2, ..., N-1 。

当男同胞们进入厕所后,他必须坐在能够使他与离他最近的人之间的距离达到最大化的坑位上。如果有多个这样的坑位,为离门近一点,他会坐在编号最小的座位上。(另外,如果厕所里没有人,那么他就坐在 0 号座位上。)

现在,假设你需要设计一个这样的东西,去预测下一个人进来会占哪个坑位(假设你是闲着无聊的看门大爷)

思路

利用set存储男同胞们占的坑位,log n 的删除和增加男同胞。

对于每一个要加入的人来说,遍历这个set,选取最大的一段区间,将其分成两段。

然后将分段点加入set。

特判 0 和 n-1 这两个特殊的位置(因为靠墙,所以不怕和墙尴尬)

代码

class ToiletObserver {
public:
    set<int> st;
    int maxs = 0;
    ToiletObserver(int n): maxs(n), st() {
    }
    
    int in() {
        int res = 0;
        if (st.size() == 0);
        else {
            int ma = *st.begin();
            int pre = *st.begin();
            for (auto v : st) {
                int mas = v - pre >> 1;
                if (mas > ma) ma = mas, res = v + pre >> 1;
                pre = v;
            }
            if ((maxs-1 - pre) > ma) res = maxs-1;
        }  
        st.insert(res);
        return res;
    }
    
    void out(int p) {
        st.erase(p);
    }
};

原题:leetcode.cn/problems/ex…