1744.你能在你最喜欢的那天吃到你最喜欢的糖果吗?
今天又是啥也不想干的一天,开始摸鱼,六一快乐鸭,祝大家都找到自己最喜欢的糖果。
原题链接:https://leetcode-cn.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day/
吐糟一下,这LeetCode题面太长,复制过来竟然会被csdn判重,就离谱,我还搞了半天排版,csdn,不太行。
思路
根据题意,在处理某个询问时,每天的吃糖数量为 1 ∼ q u e r i e s [ i ] [ 2 ] 1\sim~queries[i][2] 1∼ queries[i][2],因此我们只需要根据条件计算出 最早 和 最晚 吃到第 q u e r i e s [ i ] [ 0 ] queries[i][0] queries[i][0] 类糖果的时间,然后判断 q u e r i e s [ i ] [ 1 ] queries[i][1] queries[i][1] 是否落在这个范围内即可。若落在范围内返回则有 a n s [ i ] ans[i] ans[i]为 T r u e True True,否则为 F a l s e False False。
故问题转换为如何快速求得 最早 和 最晚 吃到第 q u e r i e s [ i ] [ 0 ] queries[i][0] queries[i][0] 类糖果的时间。
我们需要先预处理出 candiesCountcandiesCount
的前缀和数组 sum
(下标从 1 开始),方便快速求得第
i
i
i 类糖果之前有多少糖果。
为了方便,在处理某个询问时,我们令 kind = queries[i][0]
,d = queries[i][1] + 1
,v = queries[i][2]
。其中注意 d = queries[i][1] + 1
,因为题目天数是从第 0 天开始计算,而我们的计算是从 1 开始。
然后计算 最早 和 最晚 吃到第kind
类糖果的时间:
最早时间(即第一颗 kind
类糖的最早时间):当以最大速率 v
吃糖时,可以在最早时间内吃到糖。时间为吃掉第 kind
类糖果前面的所有糖果的时间(下取整)加 1 ,即:
l
=
⌊
s
u
m
[
k
i
n
d
]
c
⌋
+
1
l=\left \lfloor \frac{sum[kind]}{c} \right \rfloor + 1
l=⌊csum[kind]⌋+1
最晚时间(最后一颗 kind
类糖的最晚时间):当以最小速率 v
吃糖时,可以计算出最晚吃糖时间。时间为吃掉所有 kind
类糖的时间,即:
r
=
s
u
m
[
k
i
n
d
+
1
]
r=sum[kind+ 1]
r=sum[kind+1]
故:
a
n
s
[
i
]
=
(
d
>
=
l
&
&
d
<
=
r
)
;
ans[i] = (d >= l \quad \&\&\quad d <= r);
ans[i]=(d>=l&&d<=r);
代码
class Solution {
public:
vector<bool> canEat(vector<int>& candiesCount, vector<vector<int>>& queries) {
int m = candiesCount.size(), n = queries.size();
vector<bool> ans(n);
vector<long> sum(m + 1); //前缀和数组
for(int i = 1 ; i <= m ; i ++)
{
sum[i] = sum [i - 1] + candiesCount[i - 1];
}
for(int i = 0; i < n; i ++)
{
long kind = queries[i][0], d = queries[i][1] + 1, v = queries[i][2];
long l = (sum[kind]/v) + 1;
long r = sum[kind + 1];
ans[i] = (d >= l && d <= r);
}
return ans;
}
};