문제 보기 · Level 1 · 2018 KAKAO BLIND RECRUITMENT (1차) · 정답률 71% · 푼 사람 45,240명 (2026-09-30 기준)1
문제
한 변이 n인 정사각형 지도 두 장이 있다. 각 가로줄은 정수 하나로 주어지고, 그 정수를 n자리 이진수로 쓰면 1이 벽, 0이 공백이다. 두 장 중 하나라도 벽인 칸은 전체 지도에서도 벽이다. 전체 지도를 ‘#’과 공백으로 된 문자열 배열로 돌려준다.
- 1 ≤ n ≤ 16
- 각 정수는 0 이상 \(2^n - 1\) 이하
풀이
막히면 한 단계씩 펼친다.
필요한 개념
- 진법과 자릿수: 10진수를 n자리 이진수로 쓰기
- 비트 연산과 비트마스크: “하나라도 1이면 1”은 OR(
|) - 집합: 한 줄의 벽 칸들을 n비트 수 하나로 쓴 집합으로 보면, 두 지도를 겹치는 OR(
|)가 합집합이다.
1단계 · 작은 예로 손으로 풀기
n = 3, 첫 줄이 지도1에서 5, 지도2에서 2라고 하자.
- 5 = 101 →
# # - 2 = 010 → ` # `
- 칸마다 “하나라도 벽이면 벽” → 111 →
###
자리마다 “하나라도 1이면 1”이 바로 OR이다. 5 | 2 = 7 = 111로 한 번에 나온다.
2단계 · 가장 단순한 방법과 그 속도
두 수를 각각 이진수 문자열로 바꾸고 칸마다 비교해도 된다. n ≤ 16이라 칸은 최대 256개다. 속도는 걱정 없다. 다만 OR를 쓰면 줄마다 계산 한 번으로 끝나서 코드가 훨씬 짧다.
3단계 · 핵심 아이디어
- 줄마다 두 수를 OR 한다:
a | b - 그 결과를 정확히 n자리 이진수 문자열로 바꾼다. 앞자리 0을 채워야 한다. 5는 3자리로 “101”이지만, n = 5면 “00101”이어야 한다.
- “1”을 “#”으로, “0”을 공백으로 바꾼다.
4단계 · 코드 흐름
- 결과 리스트를 만든다.
- 두 지도의 같은 줄 수 a, b를 짝지어 꺼낸다.
a | b를 n자리 이진수 문자열로 바꾼다.- 1 → #, 0 → 공백으로 바꿔 결과에 넣는다.
5단계 · 파이썬 코드
def solution(n, arr1, arr2):
answer = []
for a, b in zip(arr1, arr2):
bits = format(a | b, f"0{n}b") # n자리 이진수, 모자라면 앞에 0
answer.append(bits.replace("1", "#").replace("0", " "))
return answer
format(x, "05b"): x를 5자리 이진수로 쓴다.b가 이진수,05가 “5자리, 앞은 0으로”다.f"0{n}b": n이 5면"05b"가 되는 f-문자열이다. 자리 수를 n에 맞춰 만든다.replace를 두 번 이어 쓴다. 앞의 결과 문자열에 다시.replace를 붙인 것이다.
6단계 · 실행 추적
n = 5, arr1 = [9, 20, 28, 18, 11], arr2 = [30, 1, 21, 17, 28]
| a | b | a | b | 5자리 이진수 | 줄 |
|---|---|---|---|---|
| 9 | 30 | 31 | 11111 | ##### |
| 20 | 1 | 21 | 10101 | # # # |
| 28 | 21 | 29 | 11101 | ### # |
| 18 | 17 | 19 | 10011 | # ## |
| 11 | 28 | 31 | 11111 | ##### |
7단계 · 복잡도와 흔한 실수
줄 n개마다 n자리 문자열을 만드니 \(O(n^2)\)이다.
bin(x)는'0b101'처럼 앞에0b가 붙고 앞자리 0이 없다. 그대로 쓰면 자리가 어긋난다.bin(x)[2:].zfill(n)이나format(x, f"0{n}b")를 쓴다.- OR(
|) 대신 AND(&)를 쓰면 “둘 다 벽이어야 벽”이 된다.
검증: 문제의 예시 2개(공백까지 정확히)를 통과했고, 무작위 입력 2,000개에서 칸마다 두 지도를 따로 비교하는 느린 풀이와 결과가 같았다 — 09_pg17681_p1.py
-
프로그래머스 스쿨, “비밀지도” (https://school.programmers.co.kr/learn/courses/30/lessons/17681), 2026-09-30 조회. ↩