感觉这次比赛时间掌握的还可以,基本能按照预想的做下来,先看了半个小时题目,然后不到一个半小时吧A跟C搞出来了,觉得题目挺水,检查了一下空间然后把数据类型开的够不够大检查了一下,没自己出数据。然后就在坑B题。想了好久。D根本没打算做,结果他们做了,还说30分很简答,晕。
B题被评测机坑了第一个点(TLE),得分70+90+100+0,名次25。xfy全场最高分,zzm280第四高分,仰慕!!!
A 数据统计
WA了3个点,不想查了。
Codeprogram vijos1061; uses math; const FileName='vijos1061';maxn=50000; var A:array[1..maxn] of int64; maxcnt,count,sum:int64; mid,ave:extended; i,n:longint; first:boolean; procedure swap(var x,y:int64); var t:int64; begin t:=x;x:=y;y:=t;end; procedure Qsort(l,r:longint); var i,j,mid:longint; begin i:=l;j:=r;mid:=A[(l+r)>>1]; repeat while(i<r)and(A[i]<mid)do inc(i); while(l<j)and(mid<A[j])do dec(j); if i<=j then begin swap(A[i],A[j]); inc(i);dec(j); end; until i>j; if(l<j)then Qsort(l,j); if(i<r)then Qsort(i,r); end; begin readln(n); for i:=1 to n do begin read(A[i]); inc(sum,A[i]); end; Qsort(1,n); ave:=sum/n;writeln(ave:2:2); if(n and 1)=1 then mid:=A[n>>1+1] else mid:=(A[n>>1]+A[n>>1])/2; writeln(mid:2:2);count:=1;maxcnt:=1; for i:=2 to n do begin if A[i]=A[i-1] then inc(count) else count:=1; maxcnt:=max(maxcnt,count); end; if maxcnt=1 then begin for i:=1 to n-1 do write(A[i],' '); writeln(A[n]); end else begin first:=true;count:=1; for i:=2 to n do begin if A[i]=A[i-1] then inc(count) else count:=1; if count=maxcnt then begin if first then begin write(A[i]); first:=false; end else write(' ',A[i]); end;end; writeln; end; end.
B 巧克力
先想到了一定切N*M-1次,肯定是选N*M-1个数加一下,然后发现很难知道什么样的切是合法的,于是想到DP发现会TLE,就不会了。看数据范围意识到要求一个O(NlogN)的算法。想到zzm神犇在群里说sort以后贪心。发现可以当成每次一刀切,然后有几块就代价乘几,然后就简单了,最后一定是每个代价在算式里出现一次,系数不一样。考虑一维发现系数严格+1,可以考虑排序不等式(好熟悉的问题——排队接水)。二维上的关系列个式子看看就知道了。
Codeprogram vijos1061B; const FileName='vijos1061B';maxn=10000; maxint64=$7fffffffffffffff; type Tarray=array[1..maxn] of int64; var n,m,xcnt,ycnt,count,ans,t:int64; x,y:tarray; i:longint; procedure swap(var x,y:int64); var t:int64; begin t:=x;x:=y;y:=t;end; procedure Qsort(var A:Tarray;l,r:longint); var i,j,mid:longint; begin i:=l;j:=r;mid:=A[(l+r)>>1]; repeat while(i<r)and(A[i]>mid)do inc(i); while(l<j)and(mid>A[j])do dec(j); if i<=j then begin swap(A[i],A[j]); inc(i);dec(j); end; until i>j; if(l<j)then Qsort(A,l,j); if(i<r)then Qsort(A,i,r); end; begin readln(T); while T>0 do begin readln(n,m); for i:=1 to n-1 do read(X[i]);X[n]:=-maxint64; for i:=1 to m-1 do read(Y[i]);Y[m]:=-maxint64; Qsort(X,1,n-1);Qsort(Y,1,m-1); xcnt:=1;ycnt:=1;ans:=0;count:=0; while count<n+m-2 do begin if X[xcnt]>Y[ycnt] then begin inc(ans,X[Xcnt]*Ycnt); inc(Xcnt);inc(count); end else begin inc(ans,Y[Ycnt]*Xcnt); inc(Ycnt);inc(count); end; end;writeln(ans); dec(T);end; end.
C 小D的旅行
我还以为是那个分层图的经典的题目来着,结果这个题只加一次油。注意到Q<n*n这个条件很奇怪,明显是告诉大家不用保存答案(?)和立方阶的算法不超时。先把floyd搞完。求s到 t 的话 枚举在i加油,ans=min{dis[s][i]+dis[i][t]+v[i]}。
Codeprogram vijos1061C; uses math; const FileName='vijos1061C';maxw=10000;maxn=300; var map:array[0..maxn,0..maxn] of int64; v:array[0..maxn] of longint; q,a,b,w,n,m,i,j,k,s,t:longint; ans,limt:int64; begin readln(n,m);limt:=n*maxw*2; fillQword(map,sizeof(map)>>3,limt); for i:=1 to n do begin readln(v[i]); map[i][i]:=0; end; for i:=1 to m do begin readln(a,b,w); map[a][b]:=min(w,map[a][b]); map[b][a]:=min(w,map[b][a]); end; for k:=1 to n do for i:=1 to n do for j:=1 to n do if(map[i][k]<limt)and(map[k][k]<limt) then map[i][j]:=min(map[i][k]+map[k][j],map[i][j]); readln(Q); while Q>0 do begin readln(s,t); if map[s][t]>limt then writeln(-1) else begin ans:=min(v[s],v[t])+map[s][t]; for i:=1 to n do if(map[s][i]<limt)and(map[i][t]<limt) then ans:=min(map[s][i]+map[i][t]+v[i],ans); writeln(ans); end; dec(Q);end; end.
D 不给糖就捣乱