不停的枚举 l ,然后枚举长度,直到所有颜色都包含,这是 n2 做法,超时。
仔细想想,可以用个队列来维护。
还是枚举 l ,用队列来维护当前区间的包含所有颜色,l 增加时再判断。
——代码
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <string> 5 # include <cmath> 6 # include <vector> 7 # include <map> 8 # include <queue> 9 # include <cstdlib> 10 # include <algorithm> 11 # define MAXN 1000001 12 using namespace std; 13 14 inline int get_num() { 15 int k = 0, f = 1; 16 char c = getchar(); 17 for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; 18 for(; isdigit(c); c = getchar()) k = k * 10 + c - '0'; 19 return k * f; 20 } 21 22 int n, k, tot, sum, h, t, ans = 1 << 30; 23 int num[MAXN]; 24 25 struct node 26 { 27 int a, pos; 28 }p[MAXN]; 29 30 inline bool cmp(node x, node y) 31 { 32 return x.pos < y.pos; 33 } 34 35 int main() 36 { 37 int i, j, m; 38 n = get_num(); 39 k = get_num(); 40 for(i = 1; i <= k; i++) 41 for(j = 1, m = get_num(); j <= m; j++) 42 p[++tot].a = i, p[tot].pos = get_num(); 43 sort(p + 1, p + n + 1, cmp); 44 for(h = 1, t = 0; h <= n; h++) 45 { 46 while(sum < k && t < n) 47 { 48 if(!num[p[++t].a]) sum++; 49 num[p[t].a]++; 50 } 51 if(sum == k) ans = min(ans, p[t].pos - p[h].pos); 52 num[p[h].a]--; 53 if(!num[p[h].a]) sum--; 54 } 55 printf("%d", ans); 56 return 0; 57 }