, , O (n * log (n)) ( n). , ( ) , ( min/max, ).
python, ( ( )).
import math
import heapq
def roundtosum(l, r):
q = 10**(-r)
d = int((round(sum(l),r) - sum([ round(x, r) for x in l ])) * (10**r))
if d == 0:
return l
elif d in [ -1, 1 ]:
c, _ = max(enumerate(l), key=lambda x: math.copysign(1,d) * math.fmod(x[1] - 0.5*q, q))
return [ round(x, r) + q * math.copysign(1,d) if i == c else round(x, r) for (i, x) in enumerate(l) ]
else:
c = [ i for i, _ in heapq.nlargest(abs(d), enumerate(l), key=lambda x: math.copysign(1,d) * math.fmod(x[1] - 0.5*q, q)) ]
return [ round(x, r) + q * math.copysign(1,d) if i in c else round(x, r) for (i, x) in enumerate(l) ]
d - , , . d , . d 1 -1, min max. heapq.nlargest D=abs(d) .
, max, nlargest ?! min max , .
, O (n + D * log (n)).
Note. With a bunch, you can create an O (n + D ^ 2 * log (D)) algorithm, since the top elements dshould be at the top levels of the D heap, and you can arrange this list in steps O (D ^ 2 * log (D) ) If nhuge, but dvery small, it can mean a lot.
(The right to re-review is reserved (because it is after midnight).