이번 문제는 너비우선탐색과 비트마스킹을 함께 사용하여 풀이하였다. 혼자의 힘으로는 접근하기에 어려웠기 때문에 구글링의 힘을 빌려서 해결하였다. 이 문제에서의 핵심은 (시도한 비밀번호) XOR (1이 k개 들어간 임의의 bit) = 비밀번호 후보
를 통해 얻은 비밀번호 후보
를 사용하여 (비밀번호 후보) XOR (시도한 비밀번호) = 1이 k개 들어간 임의의 bit
를 다시 구하게 되고 이때 임의의 bit의 1의 개수가 안전거리가 된다는 것이다.
그러므로 현재의 안전거리와 안전거리가 1 차이나는 비밀번호 후보들의 안전거리를 갱신하는 방법으로 하여 해결하였다. 너비우선탐색이기 때문에 비밀번호 후보들의 안전거리를 갱신할 때에 큐에 비밀번호 후보를 넣어주어 이 후보에 대한 탐색도 진행될 수 있도록 해야한다.
safety[i]
를 0으로 갱신한다.(1이 i개 들어간 임의의 bit) XOR (현재 비밀번호 후보)
의 값을 저장한다.safety[cur]+1
이 safety[x]
보다 작을 경우,safety[x]
를 safety[cur]+1
로 갱신한다.safety[x]
와 answer 중 더 큰 값으로 갱신한다.import collections
import sys
input=sys.stdin.readline
n=int(input())
m=int(input())
hacker=list(map(int, input().split()))
mx_len=len(bin(n)[2:])
safety=[mx_len+1 for _ in range(n+1)]
dq=collections.deque()
for i in hacker:
safety[i]=0
dq.append(i)
answer=0
while dq:
cur=dq.popleft()
for i in range(mx_len):
x=(1<<i)^cur
if x<=n and safety[cur]+1<safety[x]:
safety[x]=safety[cur]+1
answer=max(safety[x], answer)
dq.append(x)
print(answer)