LCP 08 暴力 / 二分

题意

传送门 LCP 08

题解
暴力

触发条件要求 C > = c [ i ] C >= c[i] R > = r [ i ] R >= r[i] H > = h [ i ] H >= h[i] ,则分别处理 c , r , h c, r, h , 对其排序后求各个场景的最小触发时间,在 3 3 个属性都满足触发的条件下,取最大值。

typedef pair<int, int> P;

class Solution {
public:
    vector<int> getTriggerTime(vector<vector<int>>& increase, vector<vector<int>>& requirements) {
        int n = requirements.size();
        vector<P> c(n), r(n), h(n);
        for(int i = 0; i < n; i++){
            c[i] = P(requirements[i][0], i);
            r[i] = P(requirements[i][1], i);
            h[i] = P(requirements[i][2], i);
        }
        sort(c.begin(), c.end());
        sort(r.begin(), r.end());
        sort(h.begin(), h.end());
        // 求 c, r, h 对应的最小触发时间
        vector<vector<int> > time(n, vector<int>(3, -1));
        int C = 0, R = 0, H = 0;
        int n2 = increase.size(), pc = 0, pr = 0, ph = 0;
        for(int t = 0; t <= n2; t++){
            while(pc < n && C >= c[pc].first){
                time[c[pc].second][0] = t;
                pc++;
            }
            while(pr < n && R >= r[pr].first){
                time[r[pr].second][1] = t;
                pr++;
            }
            while(ph < n && H >= h[ph].first){
                time[h[ph].second][2] = t;
                ph++;
            }
            if(t == n2) break;
            C += increase[t][0], R += increase[t][1], H += increase[t][2];
        }

        vector<int> res(n);
        for(int i = 0; i < n; i++){
            int t = -1;
            for(int j = 0; j < 3; j++){
                if(time[i][j] != -1){
                    t = max(t, time[i][j]);
                }
                else{
                    t = -1;
                    break;
                }
            }
            res[i] = t;
        }
        return res;
    }
};
二分

考虑到 c , r , h c, r, h 的单调不减性,当 t t 时刻满足触发场景的条件时, t ( t > t ) t'(t'>t) 时刻一定也满足触发条件。预先求得各个时刻的属性值,对每一个场景二分答案即可。

class Solution {
public:
    vector<int> getTriggerTime(vector<vector<int>>& increase, vector<vector<int>>& requirements) {
        int n = increase.size();
        vector<vector<int>> val(n + 1, vector<int> (3));
        int C = 0, R = 0, H = 0;
        val[0][0] = val[0][1] = val[0][2] = 0;
        for(int i = 0, j = 1; i < n; i++, j++){
            C += increase[i][0], R += increase[i][1], H += increase[i][2];
            val[j][0] = C, val[j][1] = R, val[j][2] = H;
        }
        // 对每一个 requirement 二分答案
        int n2 = requirements.size();
        vector<int> res(n2);
        for(int i = 0; i < n2; i++){
            vector<int>& req = requirements[i];
            int lb = -1, ub = n + 1;
            while(ub - lb > 1){
                int mid = (lb + ub) >> 1;
                if(val[mid][0] >= req[0] && val[mid][1] >= req[1] && val[mid][2] >= req[2]){
                    ub = mid;
                }
                else lb = mid;
            }
            res[i] = ub == n + 1 ? -1 : ub; 
        }
        return res;
    }
};
发布了110 篇原创文章 · 获赞 1 · 访问量 2035

猜你喜欢

转载自blog.csdn.net/neweryyy/article/details/105605392