蓝桥杯 第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组子串简写

我是菜鸡 勿喷 

我是先遍历一遍,用优先队列(大顶堆)去存储字符串中等于字符a的下标,并且记录a的前面有几个a; 然后从后边去遍历字符串中等于字符b的字符,并且判断优先队列中下标最大的和当前b之间的子串满不满足长度大于等于k,如果满足就加上之前所有的a,否则删去优先队列中的最大值,直到优先队列为空或者满足条件。

大佬们的一个前缀和,给我干哭了!!!

 
//AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
ll k,ans=0;
string t;
char a,b;
struct y{
    ll i,num;//i  储存下标   num储存数量
    bool operator<(const y &b)const{
        return i<b.i;
    }
};
int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>k>>t>>a>>b;
    priority_queue<y>q;
    ll cnt=0;//cnt是计数器
//     储存a
    for(ll i=0;i<t.size();i++){
        if(t[i]==a){
            cnt++;
            q.push({i,cnt});
        }
    }
//从后边枚举b
    for(ll i=t.size()-1;i>=0||q.empty();i--){
        if(q.empty())break;
                //满足条件
        if(t[i]==b){
            if(i-q.top().i+1>=k){
                y b=q.top();
                ans+=b.num;
            }else{
                                //不满足条件
                while(i-q.top().i+1<k&&!q.empty()){
                    q.pop();
                }
                if(i-q.top().i+1>=k){
                    y b=q.top();
                    ans+=b.num;
                }
            }
        }
    }
    cout<<ans;
    return 0;
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值