Editorial for DMOPC '19 Contest 7 P2 - Dinner Party
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Consider the problem on a line instead of around a circle, so the -th family member is no longer adjacent to the -th family member. Now, we serve the family members one-by-one. The -th member must be served dishes, and the only way to do so is to serve the -th and -st members simultaneously. If in doing so, we serve the -st member too many dishes, there is no solution, because we cannot satisfy the -th and -st members simultaneously: we either have to feed the -st member too many dishes, or otherwise not serve the -th member enough. If we can satisfy the -th family member, we then must satisfy the -st member by feeding the -st and -nd member simultaneously, and the problem continues for each subsequent -th and -th member for each .
Now, we return to the original problem: what if we have the option to serve the -th family member adjacent to the -th family member times before proceeding with the problem as if it were in a line? To do this, we can brute force all possible combinations of in the range for complexity, which in the worst case takes operations.
To achieve a better complexity, observe that the problem is the same given any cyclic shift of . If we can find the minimum element, and then shift such that the minimum element resides at , we can achieve complexity. Although this is deceivingly similar to our previous complexity, we see that is at most , so , meaning that our complexity is equivalent to !
Alternatively, we can represent the problem as a system of equations with odd and even cases to solve the problem in , however printing the output costs an additional and we see that in both the complexity is equivalent to anyways.
Pseudocode:
(returns original index before shifting)
function shifted(i)
return (i + idx) mod n
(checks if there is answer for some k)
function possible(k)
tmp is copy of a
tmp[0] -= k
tmp[N - 1] -= k
for i in [0, N - 1)
tmp[i + 1] -= tmp[i]
if tmp[i + 1] < 0
return false
return tmp[N - 1] == 0
(prints answer for some k)
function print_answer(k)
print "YES"
print sum / 2
do k times
print shifted(0), shifted(n - 1)
for i in [0, N - 1)
do a[i] times
a[i + 1]--
print shifted(i), shifted(i + 1)
read N, a
sum = sum of all elements in a
idx is index of minimum element in a
shift a such that a[idx] is first element
for k in [0, min(a_0, a_(n-1))]
if possible(k):
print_answer(k)
terminate
print "NO"
Time complexity:
Comments