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.

 

posted @ 2015-04-20 07:34  rpSebastian  阅读(153)  评论(0编辑  收藏  举报