原题链接:https://vjudge.net/problem/UVA-12174
分类:滑动窗口
备注:思维,细节
注意n<s的情况
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int t,n,s,a[maxn*2],ok[maxn*2],cnt[maxn];
int main(void){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--){
memset(ok,0,sizeof(ok));
memset(cnt,0,sizeof(cnt));
memset(a,0,sizeof(a));
scanf("%d %d",&s,&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
//把第一个数看作是第一组的第s,s-1,s-2,...,1个数
//ok[i]表示把第i个数看作当前窗口的第s个数是否符合条件
int tot=0;
for(int i=1,num=0;i<=s;i++){
if(i<=n)cnt[a[i]]++;
if(cnt[a[i]]>1)num++;
if(cnt[a[i]]==1)tot++;
if(num==0)ok[i]=1;
}
for(int i=s+1;i<=n;i++){
cnt[a[i]]++;
if(cnt[a[i]]==1)tot++;
cnt[a[i-s]]--;
if(cnt[a[i-s]]==0)tot--;
if(tot==s)ok[i]=1;
}
for(int i=max(n+1,s+1);i<=n+s-1;i++){
cnt[a[i-s]]--;
if(cnt[a[i-s]]==0)tot--;
if(tot==s-i+n)ok[i]=1;
}
int ans=0;
for(int i=1;i<=s;i++){
int flg=1;
for(int j=i;j<=n+s-1;j+=s)
if(!ok[j]){flg=0;break;}
if(flg)ans++;
}
printf("%d\n",ans);
}
return 0;
}
该博客详细介绍了如何使用滑动窗口算法解决UVA在线判题系统中的12174题。文章通过C++代码展示了如何处理特殊情况并计算符合条件的子序列数量。主要内容包括初始化计数器、判断窗口内元素是否唯一等步骤,旨在锻炼和提升读者的编程思维和细节处理能力。
&spm=1001.2101.3001.5002&articleId=112692361&d=1&t=3&u=c9a0eb66f2e4495491d1f6bd5c2ad6df)
329

被折叠的 条评论
为什么被折叠?



