题意
传送门 LCP 08
题解
暴力
触发条件要求 且 且 ,则分别处理 , 对其排序后求各个场景的最小触发时间,在 个属性都满足触发的条件下,取最大值。
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;
}
};
二分
考虑到 的单调不减性,当 时刻满足触发场景的条件时, 时刻一定也满足触发条件。预先求得各个时刻的属性值,对每一个场景二分答案即可。
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;
}
};