题面。
不好意思,把这道题的通过率拉低了,但坑点确实有。
思路
多出几个数据,我们可以发现,在不报警的前提下,最多可以操作数量是两个特殊字符间的最长距离。
解释
对于不报警的定义是:每次删除操作进行前,当前的字符串中的所有特殊字符的前一个位置必须不是特殊字符。
换句话说,只要当前字符串的任意一个特殊字符前仍有不是特殊字符的字符,就不会报警。
所以找到初始字符串中两个特殊字符间的最长距离,就是最多操作次数。设这两个字符的位置分别是 \(i\),\(j\),满足 \(1 \le i < j \le n\),那么最长操作数量就是 \(j - i\)。
为什么不是 \(j - i + 1\) 呢?因为操作到第 \(j - i\) 次时,距离最长的这两个特殊字符都已经贴在一起了,下一次操作必定会报警,故最长操作数量是 \(j - i\)。
代码
吐槽一句,原先的两篇题解给出的代码都超时了,别问我怎么知道的。
细节
在输入时,如果直接将 \(k\) 个字符读入的话会超时(不知道怎么回事)。因此在读入 \(k\) 时加了一点小优化,将后面的空格符也读入。(在这里被卡了好久,以后再也不想用 )cin
了。
代码实现
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#define ll long long
#define inf 0x3f3f3f3f
#define fr(i , a , b) for(register ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(register ll i = a ; i >= b ; --i)
#pragma comment(linker , "/stack : 200000000")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
inline char gchar()
{
static char buf[1000000] , *p1 = buf , *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 1000000 , stdin) , p1 == p2) ? EOF : *p1++;
}
inline ll read()
{
register ll x = 0 , f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
ll T , n , k;
char s[100005] , ch;
ll t[27] , last , max_dis;
signed main()
{
T = read();
while(T--)
{
max_dis = 0;
fr(i , 0 , 26)
{
t[i] = 0;
}
n = read();
scanf("%s" , s + 1);
k = read();
fr(i , 1 , k)
{
scanf("%c" , &ch);
getchar();
t[ch - 'a'] = 1;
}
last = 1;
fr(i , 1 , n)
{
if(t[s[i] - 'a'])
{
max_dis = max(max_dis , i - last);
last = i;
}
}
printf("%lld\n", max_dis);
}
system("pause");
return 0;
}
标签:Dorms,ch,题解,ll,CF1670B,p1,include,buf,特殊字符
From: https://www.cnblogs.com/xhqdmmz/p/18127547