codeforces round375(div.2)题解

Posted 一只蒟篛酱的日常~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces round375(div.2)题解相关的知识,希望对你有一定的参考价值。

首先吐槽一下这套题。。。为什么EF全是图论QAQ

过了ABCD四个题。。。F的并查集死磕了好久。。。

不过似乎rank还算乐观。。。(因为ABC都是一次过的QAQ)

Problem A:

啥都不想说QAQ。。。

代码如下:

 1 var a,b,c,d,max,min,ans:longint;
 2 begin
 3   readln(a,b,c);
 4   max:=a;
 5   min:=a;
 6   if (b>max) then max:=b;
 7   if (c>max) then max:=c;
 8   if (b<min) then min:=b;
 9   if (c<min) then min:=c;
10   d:=a+b+c-max-min;
11   ans:=abs(a-d)+abs(b-d)+abs(c-d);
12   writeln(ans);
13 end.
14   

Problem B:

统计字符串的题,注意一下括号里面的各种细节,以及各种单词统计的处理就可以了。

代码如下:

 1 var n,i,j,max,ans,now:longint;
 2     flag:boolean;
 3     ch:array[0..500] of char;
 4 function flagg(x:char):boolean;
 5 begin
 6   if (65<=ord(x)) and (ord(x)<=65+25) then exit(true);
 7   if (97<=ord(x)) and (ord(x)<=97+25) then exit(true);
 8   exit(false);
 9 end;
10 begin
11   readln(n);
12   for i:=1 to n do
13     read(ch[i]);
14   readln;
15   max:=0;
16   ans:=0;
17   flag:=true;
18   i:=1;
19   now:=0;
20   while (i<=n) do
21   begin
22     if flagg(ch[i]) then inc(now);
23     if not(flagg(ch[i])) then
24     begin
25       if flag then
26       begin
27         if (now>max) then max:=now;
28         now:=0;
29       end
30       else
31       begin
32         if (now>0) then inc(ans);
33         now:=0;
34       end;
35     end;
36     if (ch[i]=() then flag:=false;
37     if (ch[i]=)) then flag:=true;
38     inc(i);
39   end;
40     if (now>0) then
41     begin
42       if not(flag) then inc(ans);
43       if flag and(now>max) then max:=now;
44     end;
45     writeln(max, ,ans);
46 end.
47         

Problem C:

这题的题意需要好好理解一下。。。

首先需要看出,第一个答案就是n div m,

接下来方案只需要按照类似贪心来模拟就可以了,注意一下边界的细节。

代码如下:

 1 var n,m,i,j,ans,ans1:longint;
 2     a,flag,flag1,anss:array[0..3000] of longint;
 3 begin
 4   readln(n,m);
 5   fillchar(a,sizeof(a),0);
 6   for i:=1 to n do
 7     read(a[i]);
 8   readln;
 9   write(n div m, );
10   ans:=n div m;
11   fillchar(flag,sizeof(flag),0);
12   for i:=1 to n do
13     if (a[i]<=m) then inc(flag[a[i]]);
14   ans1:=0;
15   for i:=1 to m do
16     if (flag[i]<ans) then ans1:=ans1+ans-flag[i];
17   writeln(ans1);
18   fillchar(flag1,sizeof(flag1),0);
19   fillchar(anss,sizeof(anss),0);
20   for i:=1 to n do
21   begin
22     if (a[i]<=m) then
23     begin
24       if (flag1[a[i]]<ans) then
25       begin
26         inc(flag1[a[i]]);
27         anss[i]:=a[i];
28       end;
29     end;
30   end;
31   i:=1;
32   j:=1;
33   while (j<=m) and (flag1[j]>=ans) do inc(j);
34   while (i<=n) do
35   begin
36     if (anss[i]=0) then
37     begin
38       if (j<>m+1) then 
39       begin
40       anss[i]:=j;
41       inc(flag1[j]);
42       while (j<=m) and (flag1[j]>=ans) do inc(j);
43       end else anss[i]:=a[i];
44     end;
45     inc(i);
46   end;
47   for i:=1 to n do
48     write(anss[i], );
49   writeln;
50 end.
51     

Problem D:

这题题意似乎也没写好QAQ

这题其实就是一个DFS就可以了,由于最开始的内陆湖个数大于等于k,所以直接贪心处较小的那几个内陆湖面积,然后加起来就可以了。

注意细节,比如周围一圈算海洋,不属于内陆湖。

代码如下:

  1 const tx:array[1..4] of longint=(0,0,1,-1);
  2     ty:array[1..4] of longint=(1,-1,0,0);
  3 var n,m,k,i,j,tot,now,ans,ii,jj:longint;
  4     flag:boolean;
  5     ch:array[0..60,0..60] of char;
  6     vis:array[0..60,0..60] of boolean;
  7     r:array[0..60,0..60] of longint;
  8     area,b:array[0..2500] of longint;
  9 procedure qsort(lx,rx:longint);
 10 var i,j,m,t:longint;
 11 begin
 12   i:=lx;
 13   j:=rx;
 14   m:=area[(i+j) div 2];
 15   repeat
 16     while (area[i]<m) do inc(i);
 17     while (area[j]>m) do dec(j);
 18     if (i<=j) then
 19     begin
 20       t:=area[i];
 21       area[i]:=area[j];
 22       area[j]:=t;
 23       t:=b[i];
 24       b[i]:=b[j];
 25       b[j]:=t;
 26       inc(i);
 27       dec(j);
 28     end;
 29   until (i>j);
 30   if (i<rx) then qsort(i,rx);
 31   if (j>lx) then qsort(lx,j);
 32 end;
 33 procedure tryit(x,y:longint);
 34 var i,j,a,b:longint;
 35 begin
 36   r[x,y]:=tot+1;
 37   vis[x,y]:=true;
 38   inc(now);
 39   if (x=1) or (x=n) or (y=1) or (y=m) then flag:=false;
 40   for i:=1 to 4 do
 41   begin
 42     a:=x+tx[i];
 43     b:=y+ty[i];
 44     if (1<=a) and (a<=n) and (1<=b) and (b<=m) then
 45       if not(vis[a,b]) and (ch[a,b]=.) then tryit(a,b);
 46   end;
 47 end;
 48 procedure trycolor(t:longint);
 49 var i,j:longint;
 50 begin
 51   for i:=1 to n do
 52     for j:=1 to m do
 53         if (r[i,j]=t) then ch[i,j]:=*;
 54 end;
 55 begin
 56   readln(n,m,k);
 57   for i:=1 to n do
 58   begin
 59     for j:=1 to m do
 60         read(ch[i,j]);
 61     readln;
 62   end;
 63   fillchar(area,sizeof(area),0);
 64   fillchar(b,sizeof(b),0);
 65   fillchar(r,sizeof(r),0);
 66   tot:=0;
 67   fillchar(vis,sizeof(vis),false);
 68   for i:=2 to n-1 do
 69     for j:=2 to m-1 do
 70         if (ch[i,j]=.) and not(vis[i,j]) then 
 71         begin
 72           now:=0;
 73           flag:=true;
 74           tryit(i,j);
 75           if flag then
 76           begin
 77             inc(tot);
 78             area[tot]:=now;
 79           end
 80           else
 81           begin
 82             for ii:=1 to n do
 83                 for jj:=1 to m do
 84                     if (r[ii,jj]=tot+1) then r[ii,jj]:=0;
 85           end;
 86         end;
 87   for i:=1 to tot do
 88     b[i]:=i;
 89   qsort(1,tot);
 90   ans:=0;
 91   for i:=1 to tot-k do
 92   begin
 93     trycolor(b[i]);
 94     ans:=ans+area[i];
 95   end;
 96   writeln(ans);
 97   for i:=1 to n do
 98   begin
 99     for j:=1 to m do
100         write(ch[i,j]);
101     writeln;
102   end;
103 end.
104   
105   

Problem E:

这是一道欧拉混合回路。。。

首先,你需要大胆猜出结论,就是所有度数为偶数的最后都可以满足条件。

然后跑欧拉回路迭代构造方案就可以了。(很传统的做法)

代码如下:

 1 var t,l,m,n,i,j,ans,u,v,tot:longint;
 2     deg:array[0..300] of longint;
 3     r:array[0..100000,1..2] of longint;
 4     vis:array[0..100000] of boolean;
 5     next,last,other:array[0..100000] of longint;
 6 procedure insert(x,y:longint);
 7 begin
 8   inc(tot);
 9   next[tot]:=last[x];
10   last[x]:=tot;
11   other[tot]:=y;
12   inc(tot);
13   next[tot]:=last[y];
14   last[y]:=tot;
15   other[tot]:=x;
16 end;
17 procedure dfs(x:longint);
18 var i,j:longint;
19 begin
20   i:=last[x];
21   while (i>0) do
22   begin
23     if not(vis[i div 2]) then
24     begin
25       vis[i div 2]:=true;
26       dfs(other[i]);
27       if (i div 2<=m) then
28       begin
29         r[i div 2,1]:=x;
30         r[i div 2,2]:=other[i];
31       end;
32     end;
33     i:=next[i];
34   end;
35 end;
36 begin
37   readln(t);
38   for l:=1 to t do
39   begin
40     readln(n,m);
41     fillchar(vis,sizeof(vis),false);
42     fillchar(deg,sizeof(deg),0);
43     fillchar(r,sizeof(r),false);
44     fillchar(next,sizeof(next),0);
45     fillchar(last,sizeof(last),0);
46     fillchar(other,sizeof(other),0);
47     tot:=1;
48     ans:=0;
49     for i:=1 to m do
50     begin
51       readln(u,v);
52       insert(u,v);
53       inc(deg[u]);
54       inc(deg[v]);
55     end;
56     for i:=1 to n do
57         if (deg[i] mod 2=1) then insert(i,n+1) else inc(ans);
58     for i:=1 to n do
59         dfs(i);
60     writeln(ans);
61     for i:=1 to m do
62         writeln(r[i,1], ,r[i,2]);
63   end;
64 end.
65     

Problem F:

本场最细节的题目了。。。

首先,这是一道并查集。。。

然后就是一堆细节了,各种地方需要注意。(比如在第一次联通之后,在清除关系之前需要保留数据)

具体细节都可以看代码。

代码如下:

  1 var n,m,s,t,ds,dt,i,j,now1,now2,now3,now4,x:longint;
  2     a,b,father,fatherr,cs,ct:array[0..400000] of longint;
  3     flag1,flag2,flag,vis:array[0..400000] of boolean;
  4     flagg,flagt:boolean;
  5 function tryit(i:longint):longint;
  6 var k,t,p:longint;
  7 begin
  8   k:=i;
  9   while (father[k]<>k) do k:=father[k];
 10   t:=i;
 11   while (t<>k) do
 12   begin
 13     p:=father[t];
 14     father[t]:=k;
 15     t:=p;
 16   end;
 17    exit(k);
 18 end;
 19 function tryit1(i:longint):longint;
 20 var k,t,p:longint;
 21 begin
 22   k:=i;
 23   while (fatherr[k]<>k) do k:=fatherr[k];
 24   t:=i;
 25   while (t<>k) do
 26   begin
 27     p:=fatherr[t];
 28     fatherr[t]:=k;
 29     t:=p;
 30   end;
 31    exit(k);
 32 end;
 33 procedure mdf(a1,b1:longint);
 34 var i,j:longint;
 35 begin
 36   i:=tryit(a1);
 37   j:=tryit(b1);
 38   if (i<>j) then father[j]:=i;
 39 end;
 40 begin
 41   readln(n,m);
 42   fillchar(a,sizeof(a),0);
 43   fillchar(b,sizeof(b),0);
 44   fillchar(cs,sizeof(cs),0);
 45   fillchar(ct,sizeof(ct),0);
 46   for i:=1 to m do
 47     readln(a[i],b[i]);
 48   readln(s,t,ds,dt);
 49   for i:=1 to n do
 50     father[i]:=i;
 51   flagg:=false;
 52   for i:=1 to m do
 53   begin
 54     if (a[i]<>s) and (a[i]<>t) and (b[i]<>s) and (b[i]<>t) then mdf(a[i],b[i]);
 55     if (a[i]=s) and (b[i]=t) then flagg:=true;
 56     if (a[i]=t) and (b[i]=s) then flagg:=true;
 57   end;
 58   fillchar(flag1,sizeof(flag1),false);
 59   fillchar(flag2,sizeof(flag2),false);
 60   fillchar(flag,sizeof(flag),false);
 61   for i:=1 to n do
 62     if (i<>s) and (i<>t) then flag[tryit(i)]:=true;
 63   for i:=1 to m do
 64   begin
 65     if (a[i]=s) then 
 66     begin
 67       flag1[tryit(b[i])]:=true;
 68       cs[tryit(b[i])]:=b[i];
 69     end;
 70     if (b[i]=s) then 
 71     begin
 72       flag1[tryit(a[i])]:=true;
 73       cs[tryit(a[i])]:=a[i];
 74     end;
 75     if (a[i]=t) then 
 76     begin
 77       flag2[tryit(b[i])]:=true;
 78       ct[tryit(b[i])]:=b[i];
 79     end;
 80     if (b[i]=t) then 
 81     begin
 82       flag2[tryit(a[i])]:=true;
 83       ct[tryit(a[i])]:=a[i];
 84     end;
 85   end;
 86   now1:=0;
 87   now2:=0;
 88   now3:=0;
 89   now4:=0;
 90   for i:=1 to n do
 91     if (i<>s) and (i<>t) and flag[i] then
 92     begin
 93       if flag1[i] and not(flag2[i]) then inc(now1);
 94       if flag2[i] and not(flag1[i]) then inc(now2);
 95       if flag1[i] and flag2[i] then inc(now3);
 96       if not(flag1[i]) and not(flag2[i]) then inc(now4);
 97     end;
 98 if (now3>0) and ((now1+now2+now3+1>ds+dt) or (now1+1>ds) or (now2+1>dt)) then
 99 begin
100   writeln(No);
101   halt;
102 end
103 else if (now3=0) and (not(flagg) or (now1+now2+now3+2>ds+dt) or (now1+1>ds) or (now2+1>dt)) then
104 begin
105     writeln(No);
106     halt;
107 end
108 else
109 begin
110   writeln(Yes);
111   fatherr:=father;
112   fillchar(father,sizeof(father),0);
113   for i:=1 to n do
114     father[i]:=i;
115   flagt:=true;
116   for i:=1 to n do
117     if (i<>s) and (i<>t) and flag[i] then
118     begin
119       if flag1[i] and not(flag2[i]) then
120       begin
121         dec(ds);
122         writeln(s, ,cs[tryit1(i)]);
123         mdf(s,i);
124       end
125       else if flag2[i] and not(flag1[i]) then
126       begin
127         dec(dt);
128         writeln(t, ,ct[tryit1(i)]);
129         mdf(t,i);
130       end;
131     end;
132   for i:=1 to n do
133     if (i<>s) and (i<>t) and flag[i] then
134     begin
135       if flag1[i] and flag2[i] then
136       begin
137         if flagt and (ds>0) and (dt>0) then
138         begin
139           dec(ds);
140           dec(dt);
141           writeln(s, ,cs[tryit1(i)]);
142           writeln(t, ,ct[tryit1(i)]);
143           mdf(s,i);
144           mdf(t,i);
145           flagt:=false;
146         end else
147         if (ds>0) then
148         begin
149           dec(ds);
150           writeln(s, ,cs[tryit1(i)]);
151           mdf(s,i);
152         end else
153         begin
154           dec(dt);
155           writeln(t, ,ct[tryit1(i)]);
156           mdf(t,i);
157         end;
158       end;
159     end;
160   if flagg and flagt then
161   begin
162     dec(ds);
163     dec(dt);
164     writeln(s, ,t);
165     mdf(s,t);
166   end;
167   for i:=1 to m do
168     begin
169       if (tryit(a[i])<>tryit(b[i])) and (a[i]<>s) and (b[i]<>s) and (a[i]<>t) and (b[i]<>t) then
170       begin
171         writeln(a[i], ,b[i]);
172         mdf(a[i],b[i]);
173       end
174     end;
175 end;
176 end.
177       
178   

完结撒花!~~~

以上是关于codeforces round375(div.2)题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #375 (Div. 2) A

Codeforces Round #375 (Div. 2)

Codeforces Round #375 (Div. 2) C

Codeforces Round #375 (Div. 2)

Codeforces Round #375 (Div. 2) ABCDE

Codeforces Round #375 (Div. 2)