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
完结撒花!~~~