#10042. 「一本通 2.1 练习 8」收集雪花 || 离散化 || 双指针法 || C++ || LOJ
看到网上没有这道题的题解,所以写一下。
要标记数字是否存在,看到x<=1e9,所以考虑用离散化,然后开一个last数组,last[i]表示数字i上次出现的位置,via数组记录数离散化过的数i是否出现过。
用双指针法,固定一端l,r++,如果r位置上的数字没有出现过,当前答案就++,如果出现过,就更新当前答案,维护一下via数组和左指针。记得即时更新答案最大值。
最后输出最大值。
(我到底在讲什么
贴一下代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<map> 7 #include<algorithm> 8 #define ll long long 9 #define max(a,b) ((a)>(b)?(a):(b)) 10 #define min(a,b) ((a)<(b)?(a):(b)) 11 #define inf (int)1e8 12 typedef unsigned long long ull; 13 using namespace std; 14 ll read(){ 15 ll x=0,f=1;char c=getchar(); 16 while(c<'0'||c>'9'){if(c=='-')f*=-1; c=getchar();} 17 while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} 18 return f*x; 19 } 20 const int maxn=1e6+50; 21 struct Num{ 22 int id; 23 int data; 24 }num[maxn]; 25 bool cmp(const Num&a,const Num&b){ 26 if(a.data<b.data)return 1; 27 return 0; 28 } 29 int c[maxn],N,cnt=0,top=0,stk[maxn],ans,max_ans=1,last[maxn]; 30 int l,r; 31 bool via[maxn]; 32 int main(){ 33 N=read(); 34 for(int i=1;i<=N;i++){ 35 num[i].data=read(); 36 num[i].id=i; 37 } 38 sort(num+1,num+N+1,cmp); 39 num[0].data=-1; 40 for(int i=1;i<=N;i++){ 41 if(num[i].data!=num[i-1].data)cnt++; 42 c[num[i].id]=cnt; 43 } 44 l=1;r=1;via[c[r]]=1;ans=1;last[c[r]]=r; 45 while(l<=N&&r<N){ 46 r++; 47 if(via[c[r]]==0){ 48 ans++; 49 } 50 else { 51 for(int j=l;j<=last[c[r]];j++)via[c[j]]=0; 52 l=last[c[r]]+1; 53 ans=r-last[c[r]]; 54 } 55 via[c[r]]=1; 56 max_ans=max(max_ans,ans); 57 last[c[r]]=r; 58 } 59 printf("%d\n",max_ans); 60 return 0; 61 }
End.