사용자 도구

사이트 도구


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()

토론

댓글을 입력하세요:
E D W N M
 
ps/problems/boj/1963.txt · 마지막으로 수정됨: 2022/01/21 16:17 저자 teferi