首页 > 技术文章 > #10042. 「一本通 2.1 练习 8」收集雪花 || 离散化 || 双指针法 || C++ || LOJ

AlenaNuna 2018-08-20 13:38 原文

题目:#10042. 「一本通 2.1 练习 8」收集雪花


 

看到网上没有这道题的题解,所以写一下。

要标记数字是否存在,看到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.

推荐阅读