====== 카드2 ====== ===== 풀이 ===== * [[ps:problems:boj:2161]]에서 N의 범위를 늘리고, 마지막 남는 카드만 출력하게 변형한 문제. * N이 늘어났지만, 그래도 최대 500,000 이기 때문에 deque를 사용해서 O(n)에 구현해도 여유있게 풀리기는 한다. * 그러나 이 문제에서 카드를 조작하는 것이 요세푸스 문제와 같은 패턴이고, 전체 시퀀스가 아니라 마지막에 남는 카드만 출력하면 되기 때문에, [[ps:요세푸스 문제]]에서 설명한 효율적인 방법을 적용할 수 있다. * 여기에서는 k=2이므로, 그냥 공식에 바로 대입해서 풀 수 있다. * $ J_{n,2} = 1+2(n-2^{\lfloor{log_{2}n}\rfloor}) $ * 요세푸스 문제에서는 처음으로 제거하는 수가 2가 된다. 윗 공식의 J(n,2)도 그 경우에 마지막으로 남는 수를 찾는 공식이다. 이 문제에서는 요세푸스 문제와 달리 처음 제거하는 수가 1이다. 그래서 위의 공식에서 구한 J(n,2)에서 1을 뺀 값을 답으로 출력하면 된다. 만약 그 값이 0이 되는 경우에는 (N=2^x인 경우), N을 대신 답으로 출력해주면 된다. * 이렇게 하면 시간복잡도는 O(1) ===== 코드 ===== ==== 코드 1 - 공식을 사용 ==== """Solution code for "BOJ 2164. 카드2". - Problem link: https://www.acmicpc.net/problem/2164 - Solution link: http://www.teferi.net/ps/problems/boj/2164 """ def main(): N = int(input()) answer = ~(1 << N.bit_length()) & (N << 1) if answer == 0: answer = N print(answer) if __name__ == '__main__': main() ==== 코드 2 - Deque로 시뮬레이션 ==== """Solution code for "BOJ 2164. 카드2". - Problem link: https://www.acmicpc.net/problem/2164 - Solution link: http://www.teferi.net/ps/problems/boj/2164 """ import collections def main(): N = int(input()) deq = collections.deque(range(1, N + 1)) while deq: discarded_card = deq.popleft() deq.rotate(-1) print(discarded_card) if __name__ == '__main__': main() {{tag>BOJ ps:problems:boj:실버_4}}