博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

最长不重复 连续 子序列 zznuoj~2162

题目描述

每年做题的时候,小明都忍着打人的冲动,如今,他终于发明了一个可以穿过网线打人的工具,但是穿过网线需要破解很多层防火墙,杀毒软件啥的,对于破解连续完全不相同的防火墙串非常费时间,如果假设这些防火墙是一个数组,例如1 5 3 5,那么最坏的情况是耗时为3,即1 5 3的长度为3,故需要耗时为3,那么小明希望知道这些防火墙子串中最费时间的需要耗费的时间是多少。


 

输入

第一行输入t,代表有多少组测试数据,每组数据中的第一行有一个正整数为n(n<=1000000),代表有多少个防火墙,接下来有n个数ai(ai<=1000 000 000)。

 

输出

输出为一行,代表最大需要花费的时长。

 

样例输入

2
4
1 2 3 2
5
1 10 10 10 10

 

样例输出

3
2
题意: 求最长不重复 连续 子序列
思路: 由于数字较大,所以用map辅助 处理数组下标, 将后面重复的数字的下标记录为该数字第一次出现时的下标, 然后处理记录下标的数组, 遇到重复的数,把这个长度算出来更新起点(起点为重复数的下一个位置)
 1 #include <iostream>
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 #define MAX 1005
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<cmath>
 8 #define ll unsigned long long
 9 const int N = 1e6+10;
10 int a[N], b[N];
11 map<int, int>f;
12 int main()
13 {
14     int t, n;
15     scanf("%d", &t);
16     while(t--)
17     {
18         f.clear();
19         scanf("%d", &n);
20         int ac = 0;
21         for(int i=0; i<n; i++)
22         {
23             a[i] = i;
24             int x;
25             scanf("%d", &x);
26             if(!f[x])
27                 f[x] = ac++;
28             a[i] = f[x];
29         }///这里a数组记录处理后的下标
30         memset(b, -1, sizeof b);///全部置为-1
31         int ans = -1,  l = 0;
32         a[n] = a[n-1];
33         for(int i=0; i<=n; i++)
34         {
35             if(b[a[i]] >= l)///出现重复的
36             {
37                 int su = i-l;
38                 ans = max(ans, su);
39                 l = b[a[i]]+1;
40                 b[a[i]] = i;
41             }
42             else b[a[i]] = i;///出现一次  记录
43         }
44         printf("%d\n", ans);
45     }
46     return 0;
47 }
48 /******
49 5
50 11
51 1 5 6 1 8 9 7 6 3 2 6
52 4
53 1 2 3 2
54 5
55 1 10 10 10 10
56 ******/

 

posted @ 2018-08-16 10:49  呦呦哟  Views(435)  Comments(0Edit  收藏  举报
Live2D