标签:
这题就是瞎搞……感觉我的方法比较麻烦啊……
首先把所有的位置排个序放在队列里,然后从前向后扫,用数组记录队头和队尾指针之间的每种颜色有多少个,这样在队尾指针向后移动时,检查队首指针所指的地方颜色的珠子是否已经超过了1个,如果超过一个的话就可以把指针前移,知道队头指针所指的颜色在当前队列里只有一个,这样保证了在队尾指针确定的情况下满足每种颜色至少有一个的最小长度。扫的时候更新一下ans就可以了。
至于排序我用的是堆,因为给的数据是排好序的,所以直接建个有k个元素的堆直接搞一下就可以了,时间复杂度nlogk
代码丑的惨不忍睹……正常来说应该可以压掉三分之一的……有时间重构一下……
1 program j01; 2 type xx=record 3 c,x:longint; 4 end; 5 var q,next:array[1..1010000]of longint; 6 head,num,now:array[1..70]of longint; 7 lc,ln:array[0..1010000]of longint; 8 n,k,h,t,tt,i,j,a,b,m,ans:longint; 9 heap:array[1..70]of xx; 10 sum:array[1..70]of longint; 11 zz:array[1..1010000]of longint; 12 13 procedure add(a,b:longint); 14 begin 15 inc(tt); 16 q[tt]:=b; 17 next[tt]:=head[a]; 18 head[a]:=tt; 19 end; 20 21 function min(a,b:longint):longint; 22 begin 23 if a<b then exit(a) else exit(b); 24 end; 25 26 procedure swap(var a,b:xx); 27 var c:xx; 28 begin 29 c:=a;a:=b;b:=c; 30 end; 31 32 procedure build(i:longint); 33 begin 34 while i>1 do 35 begin 36 if heap[i].x>heap[i div 2].x then swap(heap[i],heap[i div 2]) else exit; 37 i:=i div 2; 38 end; 39 end; 40 41 procedure update(i:longint); 42 begin 43 while i*2<=m do 44 begin 45 i:=i*2; 46 if (heap[i].x<heap[i+1].x)and(i+1<=m) then inc(i); 47 if heap[i].x>heap[i div 2].x then swap(heap[i],heap[i div 2]) else exit; 48 end; 49 end; 50 51 begin 52 readln(n,k); 53 tt:=0; 54 fillchar(head,sizeof(head),0); 55 for i:=1 to k do 56 begin 57 read(num[i]); 58 for j:=1 to num[i] do 59 begin 60 read(b); 61 add(i,b); 62 end; 63 end; 64 for i:=1 to k do 65 begin 66 j:=head[i]; 67 heap[i].c:=i; 68 heap[i].x:=q[j]; 69 build(i); 70 now[i]:=j; 71 end; 72 m:=k; 73 for i:=1 to n do 74 begin 75 lc[i]:=heap[1].c; 76 ln[i]:=heap[1].x; 77 swap(heap[1],heap[m]); 78 dec(m); 79 update(1); 80 now[lc[i]]:=next[now[lc[i]]]; 81 if now[lc[i]]<>0 then 82 begin 83 inc(m); 84 heap[m].x:=q[now[lc[i]]]; 85 build(m); 86 end; 87 end; 88 h:=1; 89 fillchar(sum,sizeof(sum),0); 90 t:=1; 91 ans:=maxlongint; 92 sum[lc[1]]:=1; 93 for i:=2 to n do 94 begin 95 inc(sum[lc[i]]); 96 if sum[lc[i]]=1 then inc(t); 97 while sum[lc[h]]>1 do 98 begin 99 dec(sum[lc[h]]); 100 inc(h); 101 end; 102 if t=k then ans:=min(ans,ln[h]-ln[i]); 103 end; 104 writeln(ans); 105 end.
标签:
原文地址:http://www.cnblogs.com/oldjang/p/5690176.html