[Python] BOJ 23575 - Squid game

JongPark·2022년 8월 27일
1

Baekjoon

목록 보기
10/11
post-thumbnail

q=YXq = \lfloor \frac{Y}{X}\rfloor 라고 정의하고, 케이스를 두 가지로 나눌 수 있다.

  1. Y  (mod  X)X2Y\;(\bmod \;X) \leq \frac{X}{2}
    qq를 이진수로 나타내면
    q=ibi2i(bkbk1b0(2))q=\sum_ib_i2^i\left(b_kb_{k-1}\dots b_0(2)\right)
    로 나타낼 수 있으며, 이 때 모든 i=0,1,2,,ki=0,1,2,\dots,k 에 대해서 만약 bi=1b_i=1이면 YY에서 XX로 물을 붓고, 아니면 ZZ에서 XX로 붓는다. ( 이 때, YY에서 부은 양은 ZZ에서 부은 양보다 항상 많다. )
    Y:=Y  (mod  X)Y := Y\;(\bmod\;X) 가 되고, 물의 양을 최소화시키는 위치 역시 YY가 된다. 이 때 YX2Y \leq \frac{X}{2} 가 만족된다. 그러므로 이 과정을 거치면 최솟값의 크기가 반 이하로 줄어든다.
  1. Y  (mod  X)>X2Y\;(\bmod\;X) \gt \frac{X}{2}
    q+1q+1을 이진수로 나타내면
    q+1=ibi2i(bkbk1b0(2))q+1=\sum_ib_i2^i\left(b_kb_{k-1}\dots b_0(2)\right)
    로 나타낼 수 있으며, 이 때 모든 i=0,1,2,,k1i=0,1,2,\dots,k-1 에 대해서 만약 bi=1b_i=1이면 YY에서 XX로 물을 붓고, 아니면 ZZ에서 XX로 붓는다. ( 이 때, ZZ에서 부은 양은 YY의 전체 물의 양보다 항상 적다. )
    여기서, i=ki=k인 경우를 처리해주어야 한다. 현재 (X,Y)=(2kX,YX(q+12k))(X\rq,Y\rq)=(2^kX,Y-X(q+1-2^k)) 이며, 이 때 YY\rq를 2배 해주고 XX에서 물을 퍼오면 XX의 물의 양은 XY(mod  X)X-Y(\bmod\;X) 가 된다. 그러므로 이 과정을 거치면 최솟값의 크기가 반 이하로 줄어든다.
result = []
numlist = list(map(int, input().split()))
numlist = [[numlist[i], i + 1] for i in range(3)]
while True:
    numlist.sort()
    if numlist[0][0] == 0:
        break
    x, y = divmod(numlist[1][0], numlist[0][0])
    flag = y <= numlist[0][0] >> 1
    x += flag ^ 1
    while x > flag ^ 1:
        if x & 1:
            result.append((numlist[1][1], numlist[0][1]))
            numlist[1][0] -= numlist[0][0]
            numlist[0][0] <<= 1
        else:
            result.append((numlist[2][1], numlist[0][1]))
            numlist[2][0] -= numlist[0][0]
            numlist[0][0] <<= 1
        x >>= 1
    if flag ^ 1:
        result.append((numlist[0][1], numlist[1][1]))
        numlist[0][0] -= numlist[1][0]
        numlist[1][0] <<= 1
print(len(result))
for i in result:
    print(*i)

0개의 댓글