2019蓝桥杯人物相关性分析

用string.find()直接枚举,能拿45分不知道是哪里错误了,如果请大佬指出,如果对string.find的时间复杂度有质疑,请问度娘

#include <bits/stdc++.h>
using namespace std;
int cnt,k;
bool temp = true;
char f[2][20] = {"Alice", "Bob"};
bool check(string &a, int &pa, int &pb)//pa指的是之前Alice出现的位置
{
    bool flage = true;
    pa = a.find(f[0], ++pa);
    if (pa == -1)
        temp = false;
    if(temp&&abs((pa-1) - pb) < k&&pb)//这里加一条这个就是因为相对位置的关系
    cnt++;
    if (a[pa - 1] != ' ' && a[pa + 6] != ' ')
        flage = false;
    pb = a.find(f[1], ++pb);//++pb是因为不加的话会一直查找同一子串
    if (pb == -1)
        temp = false;
    if (a[pb - 1] != ' ' && a[pb + 6] != ' ')
        flage = false;
    return flage;
}
int main()
{
    string a;
    cin >> k;
    getchar();//吃个回车
    getline(cin, a);//用cin会卡空格,getline就完全没有这些担忧
    int pa = 0, pb = 0;
    while (1)
    {
        if (check(a, pa, pb) && abs(pa - pb) < k && temp)
        {
            cnt++;
        }
        else if (!temp)//如果没查到任意一个我们就直接退出
            break;
    }
    cout << cnt;
    return 0;
}

下面我决定换个思路用滑动窗口做这题
这边介绍一下滑动窗口,主要就是用来解决一些满足一定条件的连续区间性质的问题有兴趣的可以自己问问度娘

#include <bits/stdc++.h>
using namespace std;
int len;
string s;
bool check(int i)
{
    if (len - i < 5) return false;
    return s[i + 1] == 'l' && s[i + 2] == 'i' && s[i + 3] == 'c' && s[i + 4] == 'e';
}
bool check2(int i)
{
    if (len - i < 3)
        return false;
    return s[i + 1] == 'o' && s[i + 2] == 'b';
}
int main()
{
    int k;//这里绝对不能加关闭流读入,如果这加了getline会直接读不到
    cin >> k;
    getchar();
    getline(cin, s);
    len = s.length();
    vector<int> Alice, Bob;
    for (int i = 0; i < len; i++)
    {
        if (s[i] == 'A' && check(i))
        {
            Alice.push_back(i);
            i += 5;
        }
        else if (s[i] == 'B' && check2(i))
        {
            Bob.push_back(i);
            i += 3;
        }
    }
    int As = Alice.size(), Bs = Bob.size();
    int i = 0, j = 0;
    long long ans = 0;
    for (int q = 0; q < As; q++)
    {
        while (i < Bs && Bob[i] < Alice[q] - k - 3)
            i++; //左边界已经有些被排除的
        while (j < Bs && Bob[j] <= Alice[q] + k + 5)
            j++; //右边界
        ans += j - i;
    }
    cout << ans << "\n";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值