用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;
}