ps:problems:boj:1963
소수 경로
ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 1963 |
문제명 | 소수 경로 |
레벨 | 골드 4 |
분류 |
BFS |
시간복잡도 | O(T) |
인풋사이즈 | T<=? |
사용한 언어 | Python |
제출기록 | 36240KB / 164ms |
최고기록 | 68ms |
해결날짜 | 2022/01/21 |
풀이
- 기본적으로는 BFS로 최단 경로를 구하는 문제이다.
- 각 숫자에서 한자리만 바꿔서 만들수 있는 숫자 9*4=36개중에서 소수인 것들을 찾아서 큐에 넣어주면 된다. 매번 어떤 수가 소수인지 확인을 해야 하기 때문에, 미리 1000부터 9999까지의 소수 목록을 계산해놓을 필요가 있다.
- T가 크다면 모든 소수에 대해서 바꿀수 있는 소수들을 미리 모두 계산해서 그래프를 완성시켜놓고서, 각 테스트 케이스들에 대해서 그 그래프를 사용하는 것이, 매번 엣지들을 다시 계산하지 않아도 되니까 효율적일수 있다. T가 작은 편이라면 그래프를 전부 다 만들어 놓는 것은 방문하지 않을 노드들에도 불필요하게 엣지를 계산하게 되니까 비효율적일수 있다. 문제는 T값의 범위가 주어지지 않는다는 점.. 그냥 그래프를 완성시켜놓고 푸는 방식으로 구현했다.
- n이하의 소수 목록을 구하는 것은 O(nloglogn). 여기에서 n=10000이다. 한번 BFS를 도는데 시간복잡도는 O(V+E) 이다. V의 값은 대충 1000 정도이고 (1000~9999 사이의 소수의 갯수), E의 값은 대충 1000 * 36*0.12 정도이다. (0.12 = 10000이하의 임의의 수가 소수일 확률..). 그냥 상수취급 해버린다면 O(1)이 되기는 한다.
- 재미있게도, 'Impossible'을 출력해야 하는 경우는 생기지 않는다. 다시 말하면, 모든 4자리 소수들 사이에는 소수 경로가 존재한다.
코드
"""Solution code for "BOJ 1963. 소수 경로".
- Problem link: https://www.acmicpc.net/problem/1963
- Solution link: http://www.teferi.net/ps/problems/boj/1963
Tags: [Prime Number], [BFS]
"""
import itertools
from teflib import numtheory
from teflib import tgraph
INF = float('inf')
def main():
primes = set(numtheory.prime_list(1000, 9999))
graph = [[] for _ in range(10000)]
for num in primes:
for nk, k in itertools.pairwise([10000, 1000, 100, 10, 1]):
beg = num // nk * nk + num % k
graph[num].extend(x for x in range(beg, beg + nk, k) if x in primes)
T = int(input())
for _ in range(T):
source, dest = [int(x) for x in input().split()]
answer = tgraph.min_distance_to_dest(graph, source, dest)
print('Impossible' if answer == INF else answer)
if __name__ == '__main__':
main()
- Dependency:
ps/problems/boj/1963.txt · 마지막으로 수정됨: 2022/01/21 16:17 저자 teferi
토론