2015-4-18 经典训练1
T1:皇帝的烦恼
二分之后DP判断。
1 var v,a,b:array[0..30008] of longint; 2 n,ans,i,l,r,mid:longint; 3 function max(a,b:longint):longint; 4 begin 5 if a>b then exit(a); exit(b); 6 end; 7 function min(a,b:longint):longint; 8 begin 9 if a<b then exit(a); exit(b); 10 end; 11 function pd(x:longint):boolean; 12 begin 13 a[1]:=v[1]; b[1]:=v[1]; 14 for i:=2 to n do 15 begin 16 a[i]:=max(0,v[1]+v[i]+v[i-1]-b[i-1]-x); 17 b[i]:=min(v[i],v[1]-a[i-1]); 18 end; 19 if a[n]=0 then exit(true); exit(false); 20 end; 21 begin 22 ans:=0; 23 readln(n); 24 for i:=1 to n do 25 begin 26 readln(v[i]); 27 if v[i]+v[i-1]>ans then ans:=v[i]+v[i-1]; 28 end; 29 l:=ans; r:=ans*2; 30 while l<r do 31 begin 32 mid:=(l+r)div 2; 33 if pd(mid) then r:=mid else l:=mid+1; 34 end; 35 writeln(l); 36 end.
T2:关押罪犯
若x,y有关系 将x与y的补集, y与x的补集建立关系
1 const maxn=20008; 2 maxm=100008; 3 var eg:array[0..maxm,1..3] of longint; 4 f:array[0..maxn*2] of longint; 5 i,j,m,n,x,y,z:longint; 6 procedure swap(var a,b:longint); 7 var c:longint; 8 begin 9 c:=a;a:=b;b:=c; 10 end; 11 function find(x:longint):longint; 12 begin 13 if f[x]=x then exit(x); 14 f[x]:=find(f[x]); 15 exit(f[x]); 16 end; 17 procedure sort(l,r:longint); 18 var i,j,x:longint; 19 begin 20 i:=l; j:=r; 21 x:=eg[(l+r) div 2,3]; 22 while i<=j do 23 begin 24 while eg[i,3]>x do inc(i); 25 while x>eg[j,3] do dec(j); 26 if i<=j then 27 begin 28 swap(eg[i,1],eg[j,1]); 29 swap(eg[i,2],eg[j,2]); 30 swap(eg[i,3],eg[j,3]); 31 inc(i); 32 dec(j); 33 end; 34 end; 35 if i<r then sort(i,r); 36 if l<j then sort(l,j); 37 end; 38 begin 39 readln(n,m); 40 for i:=1 to m do read(eg[i,1],eg[i,2],eg[i,3]); 41 for i:=1 to n*2 do f[i]:=i; 42 sort(1,m); 43 for i:=1 to m do 44 begin 45 x:=find(eg[i,1]); 46 y:=find(eg[i,2]); 47 if x=y then 48 begin 49 writeln(eg[i,3]); 50 exit; 51 end; 52 f[x]:=find(eg[i,2]+n); 53 f[y]:=find(eg[i,1]+n); 54 end; 55 writeln(0); 56 end.
T3:最小函数值
观察到题中函数在(x∈N*)上单调递增,用堆维护m个元素中的最大值即可。
1 var n,m,i,j,num,x:longint; 2 a,b,c:array[0..10008] of longint; 3 f,ans:array[0..10008] of longint; 4 procedure swap(a,b:longint); 5 var temp:longint; 6 begin 7 temp:=f[a]; f[a]:=f[b];f[b]:=temp; 8 end; 9 procedure insert(x:longint); 10 var i:longint; 11 begin 12 inc(num); 13 f[num]:=x; 14 i:=num; 15 while i>1 do 16 begin 17 if f[i]>f[i div 2] then swap(i,i div 2) else break; 18 i:=i div 2; 19 end; 20 end; 21 procedure delete(x:longint); 22 var i:longint; 23 begin 24 f[1]:=f[num]; 25 dec(num); 26 i:=2; 27 while i<=num do 28 begin 29 if (i+1<=num) and (f[i+1]>f[i]) then inc(i); 30 if f[i]>f[i div 2] then swap(i,i div 2) else break; 31 i:=i*2; 32 end; 33 end; 34 begin 35 readln(n,m); 36 for i:=1 to n do readln(a[i],b[i],c[i]); 37 for j:=1 to m do 38 begin 39 x:=a[1]*j*j+b[1]*j+c[1]; 40 insert(x); 41 end; 42 for i:=2 to n do 43 for j:=1 to m do 44 begin 45 x:=a[i]*j*j+b[i]*j+c[i]; 46 if x<f[1] then 47 begin 48 delete(1); 49 insert(x); 50 end 51 else break; 52 end; 53 while num>0 do 54 begin 55 ans[num]:=f[1]; 56 delete(1); 57 end; 58 for i:=1 to m do write(ans[i],' '); 59 end.
T4:Biorhythms
直接暴力。
1 var p,e,i,d,j,n:longint; 2 begin 3 readln(p,e,i,d); 4 n:=0; 5 while p<>-1 do 6 begin 7 inc(n); 8 for j:=d+1 to 21252 do 9 if (j-p) mod 23=0 then break; 10 while j<=21252 do 11 begin 12 if (j-e) mod 28=0 then break; 13 j:=j+23; 14 end; 15 while j<=21252 do 16 begin 17 if (j-i) mod 33=0 then break; 18 j:=j+23*28; 19 end; 20 writeln('Case ',n,': the next triple peak occurs in ',j-d,' days.'); 21 readln(p,e,i,d); 22 end; 23 end.
T5:作诗。
分块。
预处理F[i][j]表示第i块到第j块的答案。
一个询问l-r,那么中间大块x-y的答案已经得到了,只要考虑l-x和y-r对答案的影响。
对于这至多2√n个数,对于每个数统计它在x-y出现次数t1,以及l-r出现次数t2,根据t1,t2的奇偶性考虑其对答案的影响。
1 const maxn=100008; 2 maxm=2008; 3 type data=record 4 p,v:longint; 5 end; 6 var i,n,c,m,block,cnt,l,r:longint; 7 block_l,block_r:array[0..maxm] of longint; 8 f:array[0..maxm,0..maxm] of longint; 9 a,belong,count,first,last:array[0..maxn] of longint; 10 ans:longint; 11 flag:array[0..maxn] of boolean; 12 b:array[0..maxn] of data; 13 function min(a,b:longint):longint; 14 begin 15 if a<b then exit(a) else exit(b); 16 end; 17 function max(a,b:longint):longint; 18 begin 19 if a>b then exit(a) else exit(b); 20 end; 21 procedure swap(var a,b:longint); 22 var c:longint; 23 begin 24 c:=a; a:=b; b:=c; 25 end; 26 procedure swap(var a,b:data); 27 var c:data; 28 begin 29 c:=a; a:=b; b:=c; 30 end; 31 procedure sort(l,r:longint); 32 var i,j,x,y:longint; 33 begin 34 i:=l; j:=r; x:=b[(l+r) div 2].p; y:=b[(l+r) div 2].v; 35 while i<=j do 36 begin 37 while (b[i].v<y) or (b[i].v=y) and (b[i].p<x) do inc(i); 38 while (b[j].v>y) or (b[j].v=y) and (b[j].p>x) do dec(j); 39 if i<=j then 40 begin 41 swap(b[i],b[j]); 42 inc(i); 43 dec(j); 44 end; 45 end; 46 if l<j then sort(l,j); 47 if i<r then sort(i,r); 48 end; 49 procedure prepare; 50 var i,j,tot:longint; 51 begin 52 for i:=1 to cnt do 53 begin 54 for j:=block_l[i] to n do count[a[j]]:=0; 55 tot:=0; 56 for j:=block_l[i] to n do 57 begin 58 if (count[a[j]] and 1=0) and (count[a[j]]>0) then dec(tot); 59 inc(count[a[j]]); 60 if count[a[j]] and 1=0 then inc(tot); 61 f[i][belong[j]]:=tot; 62 end; 63 end; 64 for i:=1 to n do 65 begin 66 b[i].p:=i; 67 b[i].v:=a[i]; 68 end; 69 sort(1,n); 70 for i:=1 to n do 71 begin 72 if first[b[i].v]=0 then first[b[i].v]:=i; 73 last[b[i].v]:=i; 74 end; 75 end; 76 function findup(x,v:longint):longint; 77 var l,r,mid,tmp:longint; 78 begin 79 l:=first[v]; 80 r:=last[v]; 81 tmp:=0; 82 while l<=r do 83 begin 84 mid:=(l+r) div 2; 85 if b[mid].p<=x then 86 begin 87 tmp:=mid; 88 l:=mid+1; 89 end 90 else r:=mid-1; 91 end; 92 exit(tmp); 93 end; 94 function finddown(x,v:longint):longint; 95 var l,r,mid,tmp:longint; 96 begin 97 l:=first[v]; 98 r:=last[v]; 99 tmp:=2000000000; 100 while l<=r do 101 begin 102 mid:=(l+r) div 2; 103 if b[mid].p>=x then 104 begin 105 tmp:=mid; 106 r:=mid-1; 107 end 108 else l:=mid+1; 109 end; 110 exit(tmp); 111 end; 112 function find(x,y,v:longint):longint; 113 begin 114 exit(max(findup(y,v)-finddown(x,v)+1,0)); 115 end; 116 function query(x,y:longint):longint; 117 var i,ans,t,t1,t2,a1,bx,by,l,r:longint; 118 begin 119 fillchar(flag,sizeof(flag),false); 120 ans:=0; 121 bx:=belong[x]; by:=belong[y]; 122 if by-bx<=1 then 123 begin 124 for i:=x to y do 125 begin 126 a1:=a[i]; 127 if flag[a1] then continue; 128 t:=find(x,y,a1); 129 if t and 1=0 then begin flag[a1]:=true; inc(ans); end; 130 end; 131 end else 132 begin 133 l:=block_l[bx+1]; 134 r:=block_r[by-1]; 135 ans:=f[bx+1][by-1]; 136 for i:=x to l-1 do 137 begin 138 a1:=a[i]; 139 if flag[a1] then continue; 140 t1:=find(x,y,a1); t2:=find(l,r,a1); t1:=t1-t2; 141 if (t1 and 1=1) and (t2 and 1=0) and (t2>0) then dec(ans); 142 if (t1 and 1=1) and (t2 and 1=1) then inc(ans); 143 if (t1 and 1=0) and (t1>0) and (t2=0) then inc(ans); 144 flag[a1]:=true; 145 end; 146 for i:=r+1 to y do 147 begin 148 a1:=a[i]; 149 if flag[a1] then continue; 150 t1:=find(x,y,a1); t2:=find(l,r,a1); t1:=t1-t2; 151 if (t1 and 1=1) and (t2 and 1=0) and (t2>0) then dec(ans); 152 if (t1 and 1=1) and (t2 and 1=1) then inc(ans); 153 if (t1 and 1=0) and (t1>0) and (t2=0) then inc(ans); 154 155 flag[a1]:=true; 156 end; 157 end; 158 exit(ans); 159 end; 160 begin 161 readln(n,c,m); 162 for i:=1 to n do read(a[i]); 163 block:=trunc(sqrt(n/ln(n)*ln(2))); 164 if n mod block=0 then cnt:=n div block else cnt:=n div block+1; 165 for i:=1 to n do belong[i]:=(i-1) div block+1; 166 for i:=1 to cnt do 167 begin 168 block_l[i]:=(i-1)*block+1; 169 block_r[i]:=i*block; 170 end; 171 block_r[cnt]:=n; 172 prepare; 173 ans:=0; 174 for i:=1 to m do 175 begin 176 readln(l,r); 177 l:=(l+ans) mod n+1; 178 r:=(r+ans) mod n+1; 179 if l>r then swap(l,r); 180 ans:=query(l,r); 181 writeln(ans); 182 end; 183 close(input); 184 end.
T6:奶牛的旅行。
分数规划。二分后转化为求负环。
http://blog.csdn.net/hhaile/article/details/8883652 (一个很好的01分数规划介绍)
1 const maxn=10008; 2 maxm=10008; 3 eps=0.001; 4 type edge=record 5 u,v,w,nt:longint; 6 end; 7 var n,m,i,num,u,v,w:longint; 8 eg:array[0..maxm] of edge; 9 val:array[0..maxn] of longint; 10 lt:array[0..maxn] of longint; 11 f:array[0..maxm] of extended; 12 b:array[0..1000000] of longint; 13 pd:array[0..maxn] of boolean; 14 d:array[0..maxn] of extended; 15 time:array[0..maxn] of longint; 16 l,r,mid:extended; 17 procedure add(u,v,w:longint); 18 begin 19 inc(num); 20 eg[num].u:=u; 21 eg[num].v:=v; 22 eg[num].w:=w; 23 eg[num].nt:=lt[u]; 24 lt[u]:=num; 25 end; 26 function spfa:boolean; 27 var i,l,r,u,v:longint; 28 begin 29 for i:=1 to n do 30 begin 31 pd[i]:=true; d[i]:=0; b[i]:=i; time[i]:=1; 32 end; 33 l:=1; r:=n; 34 while l<=r do 35 begin 36 u:=b[l]; 37 i:=lt[u]; 38 while i<>0 do 39 begin 40 v:=eg[i].v; 41 if d[u]+f[i]<d[v] then 42 begin 43 d[v]:=d[u]+f[i]; 44 inc(time[v]); 45 if time[v]>n then exit(true); 46 if not pd[v] then 47 begin 48 pd[v]:=true; 49 inc(r); 50 b[r]:=v; 51 end; 52 end; 53 i:=eg[i].nt; 54 end; 55 pd[u]:=false; 56 inc(l); 57 end; 58 exit(false); 59 end; 60 function check:boolean; 61 var i:longint; 62 begin 63 for i:=1 to num do f[i]:=mid*eg[i].w-val[eg[i].v]; 64 exit(spfa); 65 end; 66 begin 67 readln(n,m); 68 for i:=1 to n do readln(val[i]); 69 for i:=1 to m do 70 begin 71 readln(u,v,w); 72 add(u,v,w); 73 end; 74 l:=0; r:=10000; 75 while r-l>eps do 76 begin 77 mid:=(l+r)/2; 78 if check then l:=mid else r:=mid; 79 end; 80 writeln(l:0:2); 81 end.
T7:家园
枚举答案网络流判断。
1 var m,n,k,s,t,ans,sum:longint; 2 l,h,pd:array[0..100000] of longint; 3 a:array[0..3000,0..3000] of longint; 4 d:array[0..1000,0..1000] of longint; 5 dd:array[0..1000,0..1000] of boolean; 6 b:array[0..100000] of longint; 7 procedure bfs; 8 var i,head,tail,x,y:longint; 9 begin 10 fillchar(b,sizeof(b),0); 11 fillchar(h,sizeof(h),$7f); 12 h[t]:=0; 13 head:=1; tail:=1; b[1]:=t; 14 while head<=tail do 15 begin 16 x:=b[head]; 17 for i:=0 to t do 18 if (a[i,x]>0) and (h[i]>=t) then 19 begin 20 inc(tail); 21 b[tail]:=i; 22 h[i]:=h[x]+1; 23 end; 24 inc(head); 25 end; 26 end; 27 function dfs(now,inl:longint):longint; 28 var i,outl:longint; 29 begin 30 if now=t then exit(inl); 31 dfs:=0; 32 for i:=pd[now]+1 to t do 33 if (pd[i]<t) and (a[now,i]>0) and (h[now]=h[i]+1) then 34 begin 35 if a[now,i]>inl then outl:=dfs(i,inl) 36 else outl:=dfs(i,a[now,i]); 37 inl:=inl-outl; 38 dfs:=dfs+outl; 39 if (i<>t) then a[now,i]:=a[now,i]-outl; 40 if (i<>t) then a[i,now]:=a[i,now]+outl; 41 if inl=0 then break; 42 inc(pd[now]); 43 end; 44 end; 45 procedure init; 46 var i,x,j:longint; 47 begin 48 readln(n,m,k); 49 for i:=1 to m do 50 begin 51 read(l[i]); 52 read(d[i,0]); 53 for j:=1 to d[i,0] do 54 begin 55 read(d[i,j]); 56 if d[i,j]=-1 then d[i,j]:=n+2 else inc(d[i,j]); 57 if j>1 then 58 begin 59 dd[d[i,1],d[i,j]]:=true; 60 dd[d[i,j],d[i,1]]:=true; 61 end; 62 end; 63 readln; 64 end; 65 n:=n+2; 66 end; 67 procedure pan; 68 var i,j,k:longint; 69 flag:boolean; 70 begin 71 flag:=false; 72 while not flag do 73 begin 74 flag:=true; 75 for i:=1 to n do 76 for j:=1 to n do 77 for k:=1 to n do 78 if dd[i,k] and dd[k,j] and not dd[i,j] then 79 begin 80 dd[i,j]:=true; 81 flag:=false; 82 end; 83 end; 84 if not dd[1,n] then begin writeln(0); halt; end; 85 end; 86 procedure makeline; 87 var i,j,x,y:longint; 88 begin 89 s:=0; 90 t:=n*(ans+1)+1; 91 a[n*(ans+1),t]:=maxlongint; 92 for i:=1 to n do a[n*(ans-1)+i,n*ans+i]:=maxlongint; 93 for i:=1 to m do 94 begin 95 x:=ans mod d[i,0]; 96 if x=0 then x:=d[i,0]; 97 y:=x+1; 98 if y=d[i,0]+1 then y:=1; 99 a[n*(ans-1)+d[i,x],n*ans+d[i,y]]:=l[i]; 100 end; 101 end; 102 function dinic:longint; 103 var i:longint; 104 begin 105 bfs; 106 dinic:=0; 107 while h[s]<t do 108 begin 109 fillchar(pd,sizeof(pd),0); 110 dinic:=dinic+dfs(s,maxlongint); 111 bfs; 112 end; 113 end; 114 procedure main; 115 begin 116 ans:=0; 117 sum:=0; 118 a[0,1]:=k; 119 s:=0; 120 t:=n*(ans+1)+1; 121 while true do 122 begin 123 inc(ans); 124 makeline; 125 sum:=sum+dinic; 126 if sum=k then begin writeln(ans); exit; end; 127 end; 128 end; 129 begin 130 init; 131 pan; 132 main; 133 end.
T8:信号增幅仪
类似于椭圆的最小圆覆盖。
对于每个点进行旋转和压缩,转化为最小圆覆盖问题。
1 uses math; 2 type Node=record 3 x,y:extended; 4 end; 5 var p:array[0..100000] of Node; 6 O:Node; 7 r,a,b,c,d,e,f:extended; 8 i,j,k,n,k1,k2:longint; 9 function distance(a,b:Node):extended; 10 begin 11 exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))); 12 end; 13 function solve(a,b,c,d,e,f:extended):Node; 14 begin 15 solve.x:=(c*e-b*f)/(a*e-b*d); 16 solve.y:=(c*d-a*f)/(b*d-a*e); 17 end; 18 procedure rotate(var p:Node;a:extended); 19 var x,y:extended; 20 begin 21 x:=p.x*cos(a)-sin(a)*p.y; 22 y:=p.x*sin(a)+cos(a)*p.y; 23 p.x:=x; p.y:=y; 24 end; 25 begin 26 readln(n); 27 for i:=1 to n do readln(p[i].x,p[i].y); 28 readln(k1,k2); 29 for i:=1 to n do 30 begin 31 rotate(p[i],(1-k1/360)*2*pi); 32 p[i].x:=p[i].x/k2; 33 end; 34 O:=p[1]; r:=0; 35 for i:=2 to n do 36 if distance(O,p[i])>r then 37 begin 38 O:=p[i]; r:=0; 39 for j:=1 to i-1 do 40 if distance(O,p[j])>r then 41 begin 42 O.x:=(p[i].x+p[j].x)/2; 43 O.y:=(p[i].y+P[j].y)/2; 44 r:=distance(o,p[j]); 45 for k:=1 to j-1 do 46 if distance(O,p[k])>r then 47 begin 48 a:=p[i].x; b:=p[i].y; 49 c:=p[j].x; d:=p[j].y; 50 e:=p[k].x; f:=p[k].y; 51 O:=solve(2*a-2*c,2*b-2*d,c*c+d*d-a*a-b*b, 52 2*a-2*e,2*b-2*f,e*e+f*f-a*a-b*b); 53 r:=distance(O,p[k]); 54 end; 55 end; 56 end; 57 writeln(r:0:3); 58 end.