总结
这场前三题没啥问题,基本都是看完题就有思路:暴力,贪心,暴力。
最后一题看起来很多人A了,感觉应该是能做出来的,但是不太行,随手猜了个结论写了一下,WA麻了。。
明天补一下
题解
第一题
给定一个值为0和1的循环数据,求有多少个交替组。
交替组的定义:长度为3的子数组且相邻两个元素的值不同。即a[i] != a[i+1]
直接追加前两个元素到数据最后,然后从枚举a[i],a[i+1], a[i+1] (0<=i<n)是否是一个交替组。
时间:O(n)
空间:O(1)
class Solution {
public:
int numberOfAlternatingGroups(vector<int>& a) {
a.push_back(a[0]);
a.push_back(a[1]);
int n = a.size();
int ans{};
for(int i = 0; i + 2 < n; i ++){
ans += (a[i] == a[i+2] && a[i] != a[i+1]);
}
return ans;
}
};
第二题
给定一个数组a, 以及一个数b.我们可以做两种操作:
- 选中一个小于b且没有标记过的a[i],分数加一,并且b=b-a[i];
- 选中一个没有标记过的a[i], b=b+a[i],并且标记a[i];
问最多可以得到多少分?
- 由于操作1不会标记a[i],因此在操作1中我们可以重复选择a[i]。
- 由于得到的分数每次都是加一,因此我们可以考虑每次都取min(a[i]),用最少的代码拿到最多的分数。
- 由于我们每次1操作只用到min(a[i]),因此剩余的a[i]我们其实都可以加到b上。
注意需要用long long 计算,不然会G。
比赛的时候排了一下序,其实不用排序的,直接求和以及求最小值就好了。
class Solution {
public:
using L = long long;
long long maximumPoints(vector<int>& a, int b_) {
sort(begin(a), end(a));
int n = a.size();
L b = b_;
if(b < a.front()) return 0;
for(int i = 1; i < n; i ++){
b += a[i];
}
L ans = b/a[0];
return ans;
}
};
简化一下
时间:O(n)
空间:O(1)
class Solution {
public:
using L = long long;
long long maximumPoints(vector<int>& a, int b) {
L sum{b}, mi = INT_MAX;
for(auto ele: a){
sum += ele;
mi = min<L>(mi, ele);
}
if(mi > b)return 0;
sum -= mi;
return sum/mi;
}
};
第三题
和第一题一样,唯一不同的是第一题的交替组长度为3,第三题的长度为k。
考虑以下几点:
- 如果a[i...i+k-1]是一个交替组,那么对于a[i+1...i+k-1]我们是不需要判断的,因为a[i...i+k-1]已经判断过了。所以对于a[i+1...i+k-1],只需要判断a[i+k-1]!=a[i+k]。
- 如果a[i...j]是一个交替组,但是a[i...j+1]不是一个交替组,显然a[j]==a[j+1],那么以a[i]..a[j]开头的子数组都不可能是交替组。因为会包含a[j]和a[j+1]。
基于上面两点:直接枚举a[i],并且记录a[i-1...i-1+k-1]是否是交替组。
- 如果a[i-1...i-1+k-1]是交替组,那么检查a[i+k-1]!=a[i+k]:
- 如果不等,则a[i...i+k-1]也是交替组;
- 如果相等,则直接令i跳到i+k;
- 如果a[i-1...i-1+k-1]不是交替组,则直接检查a[i...i+k-1]即可:
- 如果a[i...i+k-1]是交替组,则更新标记
- 如果不是,直接将i跳转到不符合交替组定义的位置。
class Solution {
public:
int numberOfAlternatingGroups(vector<int>& a, int k) {
for(int i = 0; i < k-1; i ++){
a.push_back(a[i]);
}
int ans{};
int last{};
int n = a.size();
for(int i = 0; i+k-1 < n; i ++){
if(last){
if(a[i+k-1] != a[i+k-2]){
ans++;
}else{
last = 0;
i = i+k-2;
}
continue;
}
int flag = -1;
for(int j =1; j < k; j ++){
if(a[i+j] == a[i+j-1]){
flag = i+j-1;
break;
}
}
if(flag == -1){
last = 1;
ans++;
}else{
i = flag;
}
}
return ans;
}
};