思路:
遍历:结局是一的就加到cnt中
随后双指针枚举,快指针指向的元素是0则加到cnt,指针间距超过k,若慢指针所指的元素是
0,则cnt减去这个元素,每一轮操作完要res= max;
最后输出res+已经是1的结局契合值
流程:根据题目关键词连续区间来确定用的算法是双指针,考虑双指针的指针移动情况,写出特殊的条件,与数据维护的语句
套路:
1.用双指针滑动窗口就好了,(关键词:连续区间,序列)
此题右指针一直在移动,左指针满足某条件后移动
for(int i = 1,j = 1;i <= n;i++){
if(...)j++;
}
也有不满足某条件时,右指针移动,满足某条件时左指针移动
for(int i = 1,j = 1;i <= m;i++){
while(...)j++;
}
2.容易与双指针滑动窗口扯上关系的最值问题,在双指针前声明返回值res,有时还需要储存每一轮数据的cnt、ans,在数据变动后与res进行比较
#include <iostream>
using namespace std;
const int N = 1e7;
typedef long long ll;
int st[N],num[N];
int main(){
int n,k;
cin >> n >> k;
for(int i = 0;i < n;i++){
cin >> num[i];
}
for(int i = 0;i < n;i++){
cin >> st[i];
}
int res = 0;
for(int i = 0;i < n;i++){
if(st[i] == true) res += num[i];
}
// cout << "res = " << res;
int sum = 0,maxn = 0;
for(int i = 0,j = 0;i < n;i++){
if(st[i] == false) sum += num[i];
// cout << "sum = " << sum <<" ";
if(i - j + 1 > k){
if(st[j] == false) sum -= num[j];
j++;
}
// cout << "sum = " << sum <<" ";
maxn = max(sum,maxn);
// cout << "maxn = " << maxn << " ";
}
cout << maxn + res;
return 0;
}
********************************
题解代码
或者是用i-k来代替慢指针
只需操控一个指针,比较方便
此题是i > k + 1 后,j始终会随着i移动,且差值始终为k,所以根本不需要双指针
双指针是i,j会根据情况来改变移动情况时用的
#include<iostream>
using namespace std;
const int N = 1e6;
int main(){
bool st[N];
int a[N];
int n,k;
scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i++){
cin >> a[i];
}
for(int i = 1;i <= n;i++){
scanf("%d",&st[i]);
}
int res= 0,maxn = 0,sum = 0;
for(int i = 1;i <= n;i++){
if(st[i] == true) sum+=a[i];
else maxn += a[i];
if(i >= k + 1){
if(st[i-k] == false) {
maxn -= a[i-k];
}
}
res = max(maxn,res);
}
printf("%d",res+sum);
return 0;
}