分析
寻找长度大于等于k的c1c2串,很容易想到用尺取法
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define endl '\n'
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int k;
string str;
char a,b;
cin>>k;
cin>>str>>a>>b;
vector<int> st;
LL result=0;
for(int i=0;i<str.size();i++){
if(str[i]==a){
for(int j=i+k-1;j<str.size();j++){
if(str[j]==b){
result++;
}
}
}
}
cout<<result<<endl;
return 0;
}
不过这种方法时间复杂度为O(n^2),超时了。这里我想到了可以用单调栈来写,每次遍历到a时,则将其下标添加到单调递增栈中,每次遍历到b时,则在单调栈中找到与b相距大于等于k的那个a的下标,那么至此往前的a均符合条件。这里我采用了upper_bound函数来寻找单调栈中a的下标。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define endl '\n'
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int k;
string str;
char a,b;
cin>>k;
cin>>str>>a>>b;
vector<int> st;
LL result=0;
for(int i=0;i<str.size();i++){
if(str[i]==a){
st.push_back(i);
}else if(str[i]==b){
int w=i-k+1;
if(st.size()==0||st[0]>w)continue;//没有一个元素符合条件
if(st.back()<=w){//所有元素都满足条件
result+=st.size();
continue;
}
int p=upper_bound(st.begin(),st.end(),w)-st.begin();
result+=p;
}
}
cout<<result<<endl;
return 0;
}
采用这种方法的时间复杂度为O(nlogn),更加有效,不过要注意的是子串的数量可能撑爆int的范围,需要用long long来存储