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

 

2981번: 검문

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

www.acmicpc.net

 

 

정말 오래 고민했다.

결국 인터넷을 보고 해답을 찾았고 아직 난 멀었다..

 

내가 처음 떠올랐던 방법은 

리스트로 받은 목록중에 가장 작은 값을 범위로 하나하나 씩 다 나누면서 일일이 있나 없나를 확인했다

그 결과 시간초과가 나왔고 진짜 하루이상 고민한거 같은데 결국 모르겠어서 인터넷을 뒤져보았다.


import sys
import math

input = sys.stdin.readline

N = int(input())
A=sorted([int(input()) for _ in range(N)])
ret= []
temp=[]
for i in range(1,N):
     temp.append(A[i] - A[i-1])



gcd_=temp[0]

for i in range(1,len(temp)):
     gcd_=math.gcd(gcd_,temp[i])



for i in range(2,int(gcd_**0.5) +1):
     if gcd_ % i ==0:
          ret.append(i)
          ret.append(gcd_//i)

ret.append(gcd_)

for i in sorted(set(ret)):
     print(i,end='\n')

다른 블로그에 찾아보면 자세한 해답이 나와있겠지만 대충 방법을 말해보자면
 

R= [ 입력받은 리스트 ]

R[0]= A X M + R  
R[1]= B X M + R
R[2]= C X M + R
 
공통적으로 가진 인수는 M 과 R이다. 

 

R[0] - R[1] = (A - B) X M
R[1] - R[2] = (B - C) X M 
 
이런식으로 나타낼 수 있다.
위 식은 아래식과 같은 형태를 띄고 있는데
1 X 3 = 3
2 X 3 = 6
3 X 3 = 9... 여기서 3은 3 6 9 의 최대 공약수이다.
고로 우리는 R[0] - R[1] , R[1] - R[2]  ...이 친구들의 최대 공약수를 찾으면 M을 찾을 수 있는 것이다.
마지막으로 결과를 append할 때 for문을 끝까지 돌려서 append 할 수도 있겠지만 그렇게 되면 시간초과가 난다.
그래서 for 문을 루트까지만 돌려서 한개의 결과값을 append 하고 나머지 값은 그 친구를 나눈값을 append 하면 된다.
가령 8 = 2 X 4 로 나타낼 수 있는데 2와 곱해지는 수를 찾을때는 8 // 2 (=4) 를 하면 찾을 수 있음을 알 수 있다. 
 

 

 

'취준 > 백준' 카테고리의 다른 글

11051 - 파이썬  (0) 2022.05.06
3036 - 파이썬  (0) 2022.05.06
9184 - 파이썬  (0) 2022.05.03
1003 - 파이썬  (0) 2022.05.03
14889 - 파이썬  (0) 2022.05.02

+ Recent posts