一个班级里有 n
个学生,编号为 0
到 n - 1
。每个学生会依次回答问题,编号为 0
的学生先回答,然后是编号为 1
的学生,以此类推,直到编号为 n - 1
的学生,然后老师会重复这个过程,重新从编号为 0
的学生开始回答问题。
给你一个长度为 n
且下标从 0
开始的整数数组 chalk
和一个整数 k
。一开始粉笔盒里总共有 k
支粉笔。当编号为 i
的学生回答问题时,他会消耗 chalk[i]
支粉笔。如果剩余粉笔数量 严格小于 chalk[i]
,那么学生 i
需要 补充 粉笔。
请你返回需要 补充 粉笔的学生 编号 。
示例 1:
输入:chalk = [5,1,5], k = 22 输出:0 解释:学生消耗粉笔情况如下: - 编号为 0 的学生使用 5 支粉笔,然后 k = 17 。 - 编号为 1 的学生使用 1 支粉笔,然后 k = 16 。 - 编号为 2 的学生使用 5 支粉笔,然后 k = 11 。 - 编号为 0 的学生使用 5 支粉笔,然后 k = 6 。 - 编号为 1 的学生使用 1 支粉笔,然后 k = 5 。 - 编号为 2 的学生使用 5 支粉笔,然后 k = 0 。 编号为 0 的学生没有足够的粉笔,所以他需要补充粉笔。
示例 2:
输入:chalk = [3,4,1,2], k = 25 输出:1 解释:学生消耗粉笔情况如下: - 编号为 0 的学生使用 3 支粉笔,然后 k = 22 。 - 编号为 1 的学生使用 4 支粉笔,然后 k = 18 。 - 编号为 2 的学生使用 1 支粉笔,然后 k = 17 。 - 编号为 3 的学生使用 2 支粉笔,然后 k = 15 。 - 编号为 0 的学生使用 3 支粉笔,然后 k = 12 。 - 编号为 1 的学生使用 4 支粉笔,然后 k = 8 。 - 编号为 2 的学生使用 1 支粉笔,然后 k = 7 。 - 编号为 3 的学生使用 2 支粉笔,然后 k = 5 。 - 编号为 0 的学生使用 3 支粉笔,然后 k = 2 。 编号为 1 的学生没有足够的粉笔,所以他需要补充粉笔。
提示:
chalk.length == n
1 <= n <= 105
1 <= chalk[i] <= 105
1 <= k <= 109
第一次提交代码
看到有overflow, 仔细看了下就是没有找到错误的地方,但是又确实报了溢出的错误,反复看了看也没有看出来哪里出错了。
看了一眼答案,脑袋看起来是滑丝了一般。
class Solution {
public:
int chalkReplacer(vector<int>& chalk, int k) {
int temp = k;
int result = -1;
long long sum = accumulate(begin(chalk), end(chalk), 0);
temp = k % sum;
for (int i = 0; i < chalk.size(); i++) {
if (temp >= chalk[i]) {
temp -= chalk[i];
} else {
result = i;
break;
}
}
return result;
}
};
答案和如上代码类似就是将
原语句
long long sum = accumulate(begin(chalk), end(chalk), 0);
修改为
long long sum = accumulate(begin(chalk), end(chalk), 0LL);
如此就不得不看看accmulate函数的实现了
实现如下
template<class InputIt, class T, class BinaryOperation>
constexpr // C++20 起
T accumulate(InputIt first, InputIt last, T init,
BinaryOperation op)
{
for (; first != last; ++first) {
init = op(std::move(init), *first); // C++20 起有 std::move
}
return init;
}
在Effective Modern C++中,第一条就提到了型别推导,
T型别推导的结果,不仅依赖expr的型别还依赖paramType的形式
情况1. ParamType是个指针或者引用,但不是个万能引用
情况2.ParamType是个万能引用
情况3.ParamType既非指针也非引用
如上,满足情况3,此时为int,上面的溢出也就是正常的了。
官方解答2,用了前缀树也是很简单的