-
[BOJ 20954, Python 3] 택배 기사 민서알고리즘/BOJ 2021. 8. 31. 23:06
https://www.acmicpc.net/problem/20954
20954번: 택배 기사 민서
민서는 택배 기사이다. 활기차게 월요일을 맞은 민서는 놀라 자빠질 수밖에 없었다. 코로나19 사태로 인하여 비대면 활동이 확산되면서 택배 물량이 급증하였기 때문이다. 민서에게 배정된 택배
www.acmicpc.net
풀이
일단 x = 2의 거듭제곱 수만 살펴보면 아래와 같은 수열이 나옵니다.
A048487 - OEIS
A048487 a(n) = T(4,n), array T given by A048483. 14 1, 6, 16, 36, 76, 156, 316, 636, 1276, 2556, 5116, 10236, 20476, 40956, 81916, 163836, 327676, 655356, 1310716, 2621436, 5242876, 10485756, 20971516, 41943036, 83886076, 167772156, 335544316, 671088636, 1
oeis.org
5 * 2 ** n - 4를 토대로 이어서 생각해보면 일단 x의 다음 항인 x가 음수일 떄의 경우엔 현재 위치가 2 ** n인데, 다음 항의 위치는 - 2 ** n이므로 x = - 2의 거듭제곱 수라면 5 * 2 ** n - 4 + 2 ** (n + 1)로 생각할 수 있습니다.
이제 x의 값이 부호를 막론하고 2의 거듭제곱 수가 아닐 때를 살펴봅시다.
제 코드를 기준으로 말하면 2의 지수를 구하는 방법은 while 2 ** expo < abs(x) : expo += 1을 하여서 2 ** expo >= abs(x) 꼴이 나오게 만들었습니다.
그러면 만약 x = 5이면 expo = 3으로 2 ** 3 = 8이 나오는 것이죠.
이러면 원래 도달하지 말아야할 x = 8 부분에 도착했으니 2 ** 3만큼 빼주어 원점으로 돌아가서 x만큼 더해주면 됩니다.
그러면 공식이 아래와 같이 나옵니다.

x가 음수일 때도 똑같습니다. 만약 x = -5이면 expo = 3으로 2 ** 3 = 8이 나오게 됩니다.
이러면 -8로 이동하니까 양수일 때와 똑같이 원점으로 돌아가서 x만큼 더해주면 됩니다.
그러면 공식이 아래와 같이 나옵니다.

참고로 x = 0일 때 답은 0이니 이것만 주의해주시면 됩니다.
코드
12345678input = __import__('sys').stdin.readlinefor _ in range(int(input())):x = int(input())expo = 0while 2**expo < abs(x): expo += 1if x == 0: print(0)elif x > 0: print(5 * 2 ** expo - 4 - (2**expo - x))else: print(5 * 2 ** expo - 4 + 2 ** (expo+1) - (2**expo - abs(x)))cs '알고리즘 > BOJ' 카테고리의 다른 글
[BOJ 20956, Python 3] 아이스크림 도둑 지호 (0) 2021.08.31 [BOJ 20955, Python 3] 민서의 응급 수술 (0) 2021.08.31 [BOJ 20953, Python 3] 고고학자 예린 (0) 2021.08.31 [BOJ 20952, Python 3] 게임 개발자 승희 (0) 2021.08.25 [BOJ 20951, C++] 유아와 곰두리차 (0) 2021.08.25