Google Kickstart 2019 Round G – ‘Book Reading’ 풀이
이 포스팅에서는 Google Kickstart 2019 Round G 의 1번 문제인 ‘Book reading’의 풀이와 코드를 제공합니다.
본 풀이는 공식적인 풀이와 완벽히 일치하지 않을 수 있으며, 온라인 Submission을 통과하였습니다.
공식 풀이 및 자세한 사항은 공식 페이지를 참조하세요.
Prob A – Book Reading
문제 정보
문제 링크 : https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050e02/000000000018fd0d
카테고리 : Divisor
난이도 : 쉬움
문제 설명
N개의 페이지로 구성된 책이 있다.
이 책에서 M개의 페이지는 이미 찢어져 있다.
Q명의 사람들이 이 책을 빌려서 읽으려고 한다.
Q명의 사람들은 각각 R_i의 배수의 페이지를 읽는다.
만약 총 페이지 수가 10이고, R_i이 3이면 그 사람은 3, 6, 9 페이지를 읽는다.
모든 사람들이 읽은 페이지의 총 수를 구하여라
예제 케이스
1 11 1 2 8 2 3
결과 : 7
첫 번째 사람은 2, 4, 6, 10 페이지를 읽는다.
두 번째 사람은 3, 6, 9 페이지를 읽는다.
따라서 총 페이지 수는 7개다.
문제 풀이
Divisors – O(M * sqrt(N))
각각의 P에 대해 약수를 구한다.
이 방법은 sqrt(P)의 시간으로 구할 수 있다.
모든 M개의 P_i에 대해 구하는 시간은 O(M * sqrt(N))이다.
정수 배열 divisors를 만들어서 구해지는 약수 i에 대해 divisors[i] +=1을 해준다.
이 배열은 해당 i에 대해서 i의 배수 중에서 찢어진 페이지의 수를 나타낸다.
모든 R_i에 대해서 N // R_i는 R_i의 배수이며 N보다 작은 모든 페이지의 수를 나타낸다.
여기에 divisors[R_i]를 뺀 값은 찢어지지 않은 페이지의 수를 나타낸다.
이 값을 다 더하면 원하는 값을 구할 수 있다.
코드
def setDivisors(N, divisors):
for i in range(1, min(N + 1, int(N ** 0.5 + 1))):
if N % i == 0:
divisors[i] += 1
if (N / i) != i:
divisors[N / i] += 1
T = int(raw_input())
for tt in range(1, T + 1):
N, M, Q = [int(x) for x in raw_input().split()]
P = [int(x) for x in raw_input().split()]
R = [int(x) for x in raw_input().split()]
divisors = [0] * (N + 1)
for p in P:
setDivisors(p, divisors)
Sum = 0
for r in R:
Sum += (N // r) - divisors[r]
print "Case #" + str(tt) +": " + str(Sum)
Competition Kickstart ‘Book reading’