2021-10-06 洛谷提高B组模拟赛 A 日常
题面![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e8f2837a2d59cd2103961c8cb4faa742.png)
思路:
因为最后一个
s
u
b
t
a
s
k
subtask
subtask 不算分,所以就有了一个
O
(
26
∗
n
)
O(26*n)
O(26∗n) 的做法
因为最后的答案一定小于等于
26
26
26,那么每循环到一个位置,往后枚举,最多枚举
26
26
26 位,统计最后的长度。
至于正解的
O
(
n
)
O(n)
O(n),就用两个双指针维护合法序列的开头和结尾,模拟跳动就好了
我写的是正解
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>
#include<cmath>
#include<ctime>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=2e7+10;
ll n,len,maxn,head,tail,ans;
char s[V];
ll cnt[500];
struct node
{
ll val,id;
}a[V];
inline ll in()
{
ll res=0,f=1;
char ch;
while((ch=getchar())<'0'||ch>'9')
if(ch=='-') f=-1;
res=res*10+ch-48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-48;
return res*f;
}
int main()
{
// freopen("example2.in","r",stdin);
n=in();
scanf("%s",s);
head=0,tail=0,len=ans=1;
while(tail<=n-1)
{
if(tail>n-1)
{
ans=max(ans,len);
break ;
}
while(cnt[ll(s[tail]-'a')]==0&&tail<=n-1)
{
++cnt[ll(s[tail]-'a')];
++tail;
}
len=tail-head;
ans=max(ans,len);
while(s[head]!=s[tail])
{
--cnt[ll(s[head]-'a')];
++head;
}
--cnt[ll(s[head]-'a')];
++head;
}
cout<<ans;
return 0;
}