蓝桥杯 人物相关性分析——第十届蓝桥杯省赛C组 C++ 尺取法(双指针)

资源限制

时间限制:1.0s   内存限制:256.0MB

思路:


按照平常思考,我们会用枚举,先计算字符串中出现的每一个Alice的位置,利用双重循环计算每个Alice与每一个Bob的位置,当两位置相差不到K,则计数加一。但这样的方法时间复杂度可达到10^12 ,必定超时。

所以需要灵活运用枚举,稍稍改变一下思路。

我们可以考虑当发现第一个Alice时,位置记作A1,则当Bob出现在[A1-K-3,A1+5+K]范围内时,

(-3是因为Bob长度为3,Alice长度为5,每次只记录A和B的下标)Bob出现几个就记多少次。(这个范围是因为题中按字符来算,我们需要考虑Alice和Bob的字符长度)

同理,出现第二个Alice时,位置记作A2,按照上面相同的方法计算出现多少次。

这样就从遍历全部字符串改变成遍历一个移动区间。
参考:https://blog.csdn.net/weixin_46259848/article/details/123167845

Code

#include<bits/stdc++.h>
char s[1000001];
int numa = 0, numb = 0;//a,b的个数
int i, j, k;
long alice[1000001];//alice[i]存的是alice第i+1出现的位置
long bob[1000001];//同理
int ans, rp, lp;
int main() {
 
    scanf("%d\n", &k);//'\n'吸收换行符,防止换行符留在缓冲区中被s录入
    scanf("%s", s);
    for (i = 0; i < strlen(s); i++) {
        if ((i - 1 < 0 || s[i - 1] == '.' || s[i - 1] == ' ') && s[i] == 'A' && s[i + 1] == 'l' && s[i + 2] == 'i' && s[i + 3] == 'c' && s[i + 4] == 'e' && (s[i + 5] == '.' || s[i + 5] == ' ')) {
            alice[numa] = i;//Alice的前面如果是非法/./空格,说明它是头一次被计数
            numa++;
        }
        if ((i - 1 < 0 || s[i - 1] == '.' || s[i - 1] == ' ') && s[i] == 'B' && s[i + 1] == 'o' && s[i + 2] == 'b' && (s[i + 3] == '.' || s[i + 3] == ' ')) {
            bob[numb] = i;//同理
            numb++;
        }
    }
    for (j = 0; j < numa; j++) {
        while (bob[lp] < alice[j] - k - 3)lp++;//如果左边Bob的位置不在区间内,则将下一个Bob的位置与区间进行比对,直到区间中有第一个Bob
        while (bob[rp + 1] <= alice[j] + k + 5)rp++;//如果右边Bob的位置还在区间内,可尝试看下一个Bob是否也在区间内,直到下一个Bob的位置不在区间内,则区间中的Bob数就可以用rp-lp+1得出
        if (rp - lp + 1 > 0)
            ans += (rp - lp + 1);
    }
    printf("%d", ans);
    return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Prudento

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值