1. 문제 접근 방법
- DFS로 접근해서 문제를 해결했다
-> 한 번 접근했던 곳을 중복 접근할 때는, 방문횟수가 더 적은 경우에만 접근하도록 하는 것이 중요하다
-> 또한, 숫자를 바꿀때는 최대한 목표와 가까운 것부터 바꾸게 하는 것이 중요하다
-> 왜냐면 그래야 가장 최소 횟수로 접근할 확률이 높아지기 때문이다.
-> 또한, 최소 횟수를 넘은 케이스에 대해서 pruning해주는 것도 중요하다.
- Memoization에 대해서 좀 더 제대로 할 필요가 있다
-> 즉, 난이도가 높은 문제일수록 최적화가 중요한 문제로 대두된다는 점을 기억해야 한다
-> DP에 대해서 좀 더 제대로 공부할 필요가 있다.
- 또한 소수를 구하는 로직에 대해서도 익숙하게 구현해야 한다
-> sqrt를 사용해서 구하는 것에 익숙해져야 한다
- 다른 사람 코드를 보고 학습을 진행해야겠다.
- 이 문제는 BFS로 푸는 것이 좋다
-> 왜냐하면 BFS로 풀면, 저절로 Memoization을 고려할 필요가 없이, 가능하기 때문이다.
-> 일종의 '최단거리' 문제로 볼 수 있으므로, BFS로 푸는 것이 적합하다.
2. 내 코드
import math
T = int(input())
prime = [False]*10000
visited = [False]*10000
minCnt = int(1e9)
def isPrime(num):
for i in range(2, int(math.sqrt(num))+1):
if num % i == 0:
return False
return True
for i in range(1000, 10000):
if isPrime(i) == True:
prime[i] = True
def dfs(curr, end, cnt, path):
global minCnt
if minCnt < cnt:
return
if curr == end:
minCnt = min(minCnt, cnt)
return
one = curr // 1000
two = (curr - 1000*(one)) // 100
three = (curr - 1000*one-100*two) // 10
four = curr % 10
endOne = end // 1000
endTwo = (end - 1000*(endOne)) // 100
endThree = (end - 1000*endOne-100*endTwo) // 10
endFour = end % 10
newCurr = 0
for i in range(4):
if i == 0:
if one == endOne:
continue
newCurr = endOne*1000+two*100+three*10+four
elif i == 1:
if two == endTwo:
continue
newCurr = one*1000+endTwo*100+three*10+four
elif i == 2:
if three == endThree:
continue
newCurr = one*1000+two*100+endThree*10+four
elif i == 3:
if four == endFour:
continue
newCurr = one*1000+two*100+three*10+ endFour
if (visited[newCurr] == 0 or visited[newCurr] > cnt) and prime[newCurr] == True:
visited[newCurr] = cnt
dfs(newCurr, end, cnt+1)
for i in range(4):
for j in range(0, 10):
if i == 0:
if j != 0 and j != one:
newCurr = j*1000+two*100+three*10+four
elif i == 1:
if j != two:
newCurr = one*1000+j*100+three*10+four
elif i == 2:
if j != three:
newCurr = one*1000+two*100+j*10+four
elif i == 3:
if j != four:
newCurr = one*1000+two*100+three*10+j
if (visited[newCurr] == 0 or visited[newCurr] > cnt) and prime[newCurr] == True:
visited[newCurr] = cnt
dfs(newCurr, end, cnt+1)
for i in range(T):
a, b = map(int, input().split())
visited = [0]*10000
minCnt = int(1e9)
visited[a] = 1
dfs(a, b, 0)
if minCnt == int(1e9):
print("impossible")
else:
print(minCnt)
3. 참고 코드
- BFS를 활용했고, nextNumStr을 numStr을 활용해서 만들고,
3가지 검사 조건(visited, prime, >=1000)을 추가했다
-> BFS의 최단 거리 개념으로 이해하면 된다
import math
from collections import deque
T = int(input())
prime = [False]*10000
visited = [False]*10000
def isPrime(num):
for i in range(2, int(math.sqrt(num))+1):
if num % i == 0:
return False
return True
for i in range(1000, 10000):
if isPrime(i) == True:
prime[i] = True
def bfs(curr, end):
q = deque()
q.append((curr, 0))
visited[curr] = True
minCnt = -1
while q:
num, cnt = q.popleft()
if num == end:
minCnt = cnt
break
numStr = str(num)
for i in range(4):
for j in range(10):
nextNumStr = numStr[:i] + str(j) + numStr[i+1:]
nextNum = int(nextNumStr)
if visited[nextNum] == False and prime[nextNum] and nextNum>=1000:
visited[nextNum] = True
q.append((nextNum, cnt+1))
return minCnt
for i in range(T):
a, b = map(int, input().split())
visited = [0]*10000
ans = bfs(a, b)
if ans == -1:
print("impossible")
else:
print(ans)
'PS' 카테고리의 다른 글
탈주범 검거 [SWEA 모의 역량 테스트] (0) | 2023.10.08 |
---|---|
등산로 조성 [SWEA 모의 SW 역량 테스트] (1) | 2023.10.08 |
벽 부수고 이동하기 [백준 2206] (0) | 2023.10.07 |
안전 영역 [백준 2468] (0) | 2023.10.07 |
스타트 택시 [삼성 기출] (0) | 2023.10.07 |