일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- nontrivial solution
- matrix trnasformations
- 빅세타
- 랜덤 순서 배열
- Big-Oh notation
- 알고리즘 분석의 실례
- 재귀함수
- 페이지 겹칩
- nonhomogeneous linear system
- 이진 탐색
- linear dependence
- 일차변환
- itertools
- Big-Oh 예제
- includepdf
- Big-O 예제
- homogeneous linear system
- 빅오메가
- recursive algorithms
- python
- Big Theta
- 배열 섞기
- Big Omega
- matrix fo a linear transformation
- trivial solution
- NumPy
- 코틀린 시작하기
- one-to-one
- 빅오 표기법
- 코틀린 Hello World!
- Today
- Total
코딩 연습
프로젝트 오일러 127번 본문
The radical of n, rad(n), is the product of distinct prime factors of n. For example, 504=23×32×7, so rad(504)=2×3×7=42.
We shall define the triplet of positive integers (a,b,c) to be an abc-hit if:
1. GCD(a,b)=GCD(a,c)=GCD(b,c)=1
2. a<b
3. a+b=c
4. rad(abc)<c
For example, (5,27,32) is an abc-hit, because:
1. GCD(5,27)=GCD(5,32)=GCD(27,32)=1
2. 5<27
3. 5+27=32
4. rad(4320)=30<32
It turns out that abc-hits are quite rare and there are only thirty-one abc-hits for c<1000, with ∑c=12523.
Find ∑c for c<120000.
rad(n) 은 자연수 n 의 소인수들을 모두 곱한 값이다. 예를 들어, 504=23×32×7 이기 때문에 rad(n)=2×3×7=42 가 된다.
또한 세 자연수 (a,b,c) 가 다음의 네 가지 조건을 만족시키면 abc-hit 이라고 한다. (GCD(a,b) 는 a,b의 최대 공약수를 나타낸다.)
1. GCD(a,b)=GCD(a,c)=GCD(b,c)=1
2. a<b
3. a+b=c
4. rad(abc)<c
예를 들어, (5,27,32) 는 abc-hit 가 된다. 왜냐하면 네 가지 조건
1. GCD(5,27)=GCD(5,32)=GCD(27,32)=1
2. 5<27
3. 5+27=32
4. rad(4320)=30<32
를 만족시키기 때문이다.
이러한 abc-hit은 매우 드물게 발생하기 때문에 c<1000 일 때, 31 가지 경우만 있고, 31 가지 경우에 대해서 모든 c 값들을 더하면 ∑c=12523 이 된다.
c<120000 에 대해서 abc-hit 가 되는 모든 경우의 c 값들을 더한 ∑c 를 구하시오.
이 문제를 풀기 위해서 꼭 알아야 할 것이 바로 유클리드 호제법이다. 유클리드 호제법은 a,b(a>b) 의 최대 공약수는 a 를 b 로 나눈 나머지 r과 b 의 최대공약수와 같다는 것이다. "유클리드 호제법" 게시물을 참고하기 바란다.
유클리드 호제법에 의하면 a,c 가 서로소이면 유클리드 호제법과 위의 세 번째 조건에 의하여 자연스럽게 a,b 와 b,c 도 서로소가 된다. 따라서 우리가 체크해야 할 것은 a,c 가 서로소인지 아닌지만 확인하면 된다.
다음으로 c 값은 3≤c<120000 범위에서 루프를 돌리고, 이 때 b=c−a 이고 a<b 이어야 하므로 다음과 같은 a 의 범위에서 두 번째 루프를 돌리면 된다.
1. c 가 홀수이면 1≤a≤c//2 (단, c//2 는 c 를 2 로 나눈 몫)
2. c 가 짝수이면 1≤a≤(c//2)−1
이제 위의 네 번째 조건을 만족시키는지 확인만 하면 되는데, 이것은 이미 124번에서 rad 를 구하는 방법을 배웠으므로 1≤n≤120000 범위에서 rad(n) 을 구하여 이 값을 사용하면 된다. 따라서 rad(a)×rad(c−a)×rad(c)<c 인지 확인만 하면 되는 것이다.
첫 번째 시도에서는 a와 c 가 서로소인지를 먼저 확인하고 나서 rad(a)×rad(c−a)×rad(c)<c 조건을 확인했는데, 생각해보니 abc-hit 가 되는 경우가 매우 드물게 발생한다고 했으므로, 먼저 rad(a)×rad(c−a)×rad(c)<c 인지 확인하고 나서 a,c 가 서로 소인지를 확인하는 것이 시간을 조금 더 절약해 준다는 것을 알 수 있었다. (물론 시행착오를 거쳐서)
이런 방법으로 문제에서 요구하는 답을 구해낼 수 있다. 하지만 여전히 시간이 상당히 오래 걸린다. 뭔가 더 나이스한 방법이 있을 것 같은데, 아직까지 내 머리에서 나올 수 있는건 여기까지 인듯....ㅠㅠ
'project euler with python' 카테고리의 다른 글
프로젝트 오일러 129번 (0) | 2016.03.15 |
---|---|
프로젝트 오일러 128번 (0) | 2016.03.15 |
프로젝트 오일러 126번 (0) | 2016.03.15 |
프로젝트 오일러 125번 (0) | 2016.03.15 |
프로젝트 오일러 124번 (0) | 2016.03.15 |