NexTopper's blog

By NexTopper, history, 15 months ago, In English

How to solve this Photoshoot problem in O(n) ? The best I could come up with is a O(n^2) idea.Would be greatful for some hints.

  • Vote: I like it
  • -10
  • Vote: I do not like it

»
15 months ago, # |
Rev. 2   Vote: I like it +11 Vote: I do not like it

When $$$n=2$$$, the answer is 1 2.

When $$$n=3$$$, we can brute-force the answer.

Consider when $$$n \geq 4$$$. An observation is that $$$b_i-b_{i-1}=a_{i + 1} - a_{i - 1}$$$. Now we can look at odd and even indices separately. For odd indices, we only have to find the index $$$k_1$$$ that gives the smallest value among all odd indices. Similarly, we find index $$$k_2$$$ that gives the smallest value among all even indices. With these, if we fix the value of $$$a_{k_1}$$$, all odd elements are known, which gives the smallest value of even elements. Then we can fill all even positions. (Or we can first fix the value of $$$a_{k_2}$$$ and do similar things)

Now we can just discuss two cases, whether $$$a_i=1$$$ for some odd $$$i$$$, or $$$a_i=1$$$ for some even $$$i$$$. We can just try both cases and check if the answer we get from one case fits the requirements.

Here is my (ugly) implementation. I'm not sure if this is the simplest $$$O(n)$$$ solution though.

»
15 months ago, # |
  Vote: I like it +1 Vote: I do not like it

Let a1 = x. For sample B = [4, 6, 7, 6] you get A = [x, 4-x, 2+x, 5-x, x+1]. Since it is guaranteed an answer exists, all the x + k "positive" terms and -x + k "negative" terms have different constants k. For each category (positive or negative), set the smallest term to be equal to 1 and check.

Code

with open("photo.in") as fi:
    N = int(fi.readline())
    B = list(map(int, fi.readline().split()))

A = [[1, 0]]
for b in B:
    A.append([-A[-1][0], b - A[-1][1]])

x1 = 1 - min(A[::2])[1]
x2 = min(A[1::2])[1] - 1
for x in sorted([x1, x2]):
    ans = [sign * x + b for sign, b in A]
    if sorted(ans) == list(range(1, N + 1)):
        with open("photo.out", "w") as fo:
            print(*ans, file=fo)
        break