[파이썬] 2981번. 검문 풀이

2023. 2. 21. 19:34·알고리즘과 코딩 테스트/백준 25단계

잘 생각해보자. N개의 주어진 수가 각각 A, B, C 라고 하자.

 

이때, 문제에 따르면 A, B, C를 이렇게 M으로 표현할 수 있다.

A = M x a(미지수인 몫) + R(항상 일정한 나머지)

B = M x b + R

C = M x c + R 

 

여기서 R을 제거하기 위해 A에서 B를, B에서 C를 뺀다고 하면 다음과 같은 식이 성립한다.

A - B = M(a - b)

B - C = M(b - c)

그렇다면 M은 A-B 와 B-C의 공약수이다.

 

이런 원리로, A~Z까지 입력받은 모든 수에 대해(오름차순), M은 B - A, C - B, ...... Z - Y의 공약수들이다.

즉, 이웃한 것끼리 뺀 수들의 최대공약수의, 1을 제외한 모든 약수가 M이 될 수 있는 것이다.

 

from math import gcd
from math import sqrt
import sys

N = int(input())

num_list = []
for _ in range(N):
    num_list.append(int(sys.stdin.readline().strip()))

num_list.sort()
sub_list = []
for i in range(N - 1):
    sub_list.append(num_list[i + 1] - num_list[i])

tour_gcd = sub_list[0] # N이 딱 2개인 경우, 두 수를 뺀 값이 단 하나의 M이기 때문이다.
for i in range(1, len(sub_list)):
    tour_gcd = gcd(tour_gcd, sub_list[i])

 


여기까지 최대공약수(tour_gcd)를 구했다. 이제 이 최대공약수의 1을 제외한 약수들이 문제를 만족하는 모든 M들이다.

하지만 문제의 입력은 10억을 넘어가기 때문에 일반적으로 약수를 구하면 시간복잡도가 증가한다.

 

이 때 약수를 구하는 반복문을 최대공약수의 제곱근(루트)만큼 줄일 수 있다.

예를 들어, 36의 경우 약수는 1 2 3 4 6 9 12 18 36 이다.

잘 보면, 제곱근인 6 이전의 모든 수에 대해, 1 x 36 = 36, 2 x 18 = 36, 이런 식으로 제곱근보다 큰 어떤 약수와 매칭되어 원래의 수를 이루기 때문에 그 두개의 수를 한번에 카운팅해주면 된다. 

 

divisor_list = []
for i in range(2, int(sqrt(tour_gcd)) + 1):
    if (tour_gcd % i == 0):
        divisor_list.append(i)
        divisor_list.append(tour_gcd // i)
divisor_list.append(tour_gcd)
# 마지막에 최대공약수 자기 자신도 추가해야 한다!

divisor_list = list(set(divisor_list)) # 리스트 중복 원소 제거
divisor_list.sort()

print(*divisor_list) 
# Asterisk(*)의 기능 중 하나는 컨테이너 타입의 데이터를 Unpacking 할 수 있다.

 

https://www.acmicpc.net/problem/2981

 

2981번: 검문

트럭을 타고 이동하던 상근이는 경찰의 검문을 받게 되었다. 경찰은 상근이가 운반하던 화물을 하나하나 모두 확인할 것이기 때문에, 검문하는데 엄청나게 오랜 시간이 걸린다. 상근이는 시간

www.acmicpc.net

 

'알고리즘과 코딩 테스트 > 백준 25단계' 카테고리의 다른 글

[파이썬] 2004번. 조합 0의 개수 풀이  (0) 2023.02.24
[파이썬] 9375번. 패션왕 신해빈 풀이  (0) 2023.02.22
[파이썬] 1002번. 터렛 풀이  (0) 2023.02.20
[파이썬] 2477번. 참외밭 풀이  (0) 2023.02.13
[파이썬] 3009번. 네 번째 점 풀이  (0) 2023.02.12
'알고리즘과 코딩 테스트/백준 25단계' 카테고리의 다른 글
  • [파이썬] 2004번. 조합 0의 개수 풀이
  • [파이썬] 9375번. 패션왕 신해빈 풀이
  • [파이썬] 1002번. 터렛 풀이
  • [파이썬] 2477번. 참외밭 풀이
달거달거
달거달거
개발자를 꿈꿉니다
  • 달거달거
    SWEE IT
    달거달거
  • 전체
    오늘
    어제
    • 분류 전체보기 (288)
      • 개발 환경 (5)
        • VSCode (1)
        • 파이썬 (Anaconda) (1)
        • Git (1)
        • Flutter (0)
        • Kotlin (1)
      • Spring (5)
        • 스프링 부트와 JPA 실무 완전 정복 로드맵 (2)
        • 스프링 부트와 AWS로 구현하는 웹 서비스 (1)
        • 채쌤의 스프링 부트 프로젝트 (1)
      • 알고리즘과 코딩 테스트 (16)
        • 파이썬 문법 (2)
        • 백준 25단계 (10)
        • 프로그래머스 코딩 테스트 고득점 Kit (1)
        • 코틀린 문법 (1)
      • 요리 (236)
      • 데이터베이스 (2)
        • MySQL (2)
      • 안드로이드 (11)
        • 연습 코드 (6)
        • 도서 내용 정리 (4)
      • Dart와 Flutter (5)
        • 도서 내용 정리 (4)
        • Flutter 위젯 정리 (1)
        • 15개 프로젝트 (2)
      • 피그마 (0)
        • 도서 내용 정리 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    mysql
    c++
    문법
    Flutter
    JPA
    node.js
    코틀린
    파이썬
    백준
    안드로이드
    docker
    코딩 테스트
    데이터베이스
    티스토리챌린지
    오블완
    자취요리
    아나콘다
    피그마
    AWS
    git
    C
    vscode
    머신러닝
    주석
    프로그래머스
    알고리즘
    spring
    DART
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
달거달거
[파이썬] 2981번. 검문 풀이
상단으로

티스토리툴바