ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 2087 |
문제명 | 암호문 |
레벨 | 골드 1 |
분류 |
meet in the middle |
시간복잡도 | O(2^(n/2)) |
인풋사이즈 | n<=40 |
사용한 언어 | Python 3.11 |
제출기록 | 171156KB / 1764ms |
최고기록 | 1764ms |
해결날짜 | 2023/08/18 |
"""Solution code for "BOJ 2087. 암호문".
- Problem link: https://www.acmicpc.net/problem/2087
- Solution link: http://www.teferi.net/ps/problems/boj/2087
Tags: [mitm]
"""
from teflib import backtracking
def main():
n = int(input())
a = [int(input()) for _ in range(n)]
K = int(input())
bit_by_subset_sums = {0: 0}
for i, a_i in enumerate(a[: n // 2], start=1):
for sum_, bit in list(bit_by_subset_sums.items()):
bit_by_subset_sums[sum_ + a_i] = bit | (1 << (n - i))
pos = n - n // 2 - 1
for sum_, inds in backtracking.subsets(
a[n // 2 :], 0, lambda s, num: None if s + num > K else s + num
):
if (left_bit := bit_by_subset_sums.get(K - sum_)) is not None:
right_bit = sum(1 << (pos - i) for i in inds)
answer = format(left_bit + right_bit, f'0{n}b')
print(answer)
break
if __name__ == '__main__':
main()