- 문제 : https://www.acmicpc.net/problem/16397
Gold Lv4 문제이고, 풀이 없이 풀었다. 생각보다 조건을 세세하게 나눴어야 해서 여러번 시도를 했던 문제이다.
문제 이해
- A, B 버튼을 t번 이하로 눌러서 n을 g로 최소 시간 안에 만들 수 있는지 확인하는 문제다. 만약 못 만든다면 ANG를 출력한다.
- A 버튼과 B 버튼의 동작방식은 다음과 같다.
A 버튼 : (이전 수) + 1
B 버튼 : (이전 수) * 2 -> 가장 큰 자릿수 - 1
- 실패하는 케이스도 잘 생각해야하는데, 만약 A버튼을 누르거나, B 버튼에서 곱하기 2를 했을 때 10 ** 6 이상이 되면 실패한 케이스이다.
- 풀면서 헤맸던 부분은 다음과 같다.
1. bfs인데 방문한 노드를 visit 처리하지 않았던 것
2. 다음 노드가 범위 내(1 이상 99999 이하)여야 한다는 것이다.
3. A버튼과 B버튼이 이동방식이 달라서 visit 처리를 해줘야하는 노드들도 다르다.
풀이 로직
- n, t, g를 입력값으로 받고, 방문하는 숫자들을 처리하기 위해 visit를 초기화 한다. (최대 숫자가 99999이므로 길이는 넉넉하게 10 ^ 5 + 1)
- queue에 n을 추가한 다음 while문으로 bfs를 진행한다.
- 방문한 노드가 g와 같고, visit[number] - 1 값이 t 이하라면 정답이므로 visit[number] - 1을 출력한 뒤 while 문을 break한다. (visit 시작 값이 1로 시작해서 정답과 1 차이가 나기 때문에 -1을 해줬다)
- 방문한 노드가 g가 아니라면 다음 노드로 이동하는데, 다음 노드가 범위 내 [1, 99999]에 있는지 확인한다. 만약 다음 노드가 범위 내에 없다면 문제에서 바로 실패라고 했으므로 for문을 break한다.
- 다음 노드가 범위 내에 있을 때, A 버튼인지 B 버튼인지에 따라 다음 노드 값이 달라진다.
A 버튼인 경우는 number + 1를 방문하지 않은 경우 이동할 수 있고, 이에 따라 visit 처리하고, queue에 추가하면 된다.
if each == number + 1:
if not visit[each]:
queue.append(each)
visit[each] = visit[number] + 1
B 버튼인 경우 2 * number가 다음 노드가 아니라 2배 한 뒤 최대 자리수 값을 -1 해야한다. 그래야 최종값인 temp가 된다.
이 temp를 방문하지 않은 경우 방문 처리 후, queue에 추가하면 된다.
elif each == number * 2:
count = len(str(each))
temp = each - 10 ** (count - 1)
if not visit[temp]:
queue.append(temp)
visit[temp] = visit[number] + 1
- while문을 다 돌았는데도 정답을 출력하지 못했으면 실패한 것이므로 ANG를 출력한다.
정답 풀이
항상 visit 배열로 방문 여부 확인해야 시간초과 안 뜨고,
다음 노드가 범위 내에 있는지 확인 해야함
이 문제에서는 다음 노드가 어디인지에 따라 노드 값이 변형될 수 있으므로 그 부분 주의하기
from collections import deque
n, t, g = map(int, input().split())
queue = deque() # 숫자, 횟수
queue.append(n)
flag = False
visit = [0] * (10 ** 5 + 1)
visit[n] = 1
while queue:
number = queue.popleft()
if number == g:
if visit[number] - 1 <= t:
flag = True
print(visit[number] - 1)
break
for each in [number + 1, number * 2]:
if 1 <= each <= 99999 :
if each == number + 1:
if not visit[each]:
queue.append(each)
visit[each] = visit[number] + 1
elif each == number * 2:
count = len(str(each))
temp = each - 10 ** (count - 1)
if not visit[temp]:
queue.append(temp)
visit[temp] = visit[number] + 1
else:
break
if flag == False:
print('ANG')
삽질기록,,,
'백준 > Search' 카테고리의 다른 글
[bfs/백준] 1039번 : 교환 (0) | 2023.05.26 |
---|---|
[bfs/백준] 9019번 : DSLR (0) | 2023.05.26 |
[bfs/백준] 3055번 : 탈출 (0) | 2023.05.25 |
[bfs/백준] 5427번 : 불 (0) | 2023.05.22 |
[bfs/백준] 2206번 : 벽 부수고 이동하기 (0) | 2023.05.20 |