상세 컨텐츠

본문 제목

[Python] 백준 17626번 - Four Squares

STUDY/__Coding Test

by 2_54 2022. 2. 4. 01:37

본문

문제 링크 : https://www.acmicpc.net/problem/17626

 

17626번: Four Squares

라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다. 어떤 자연수는 복수의 방법으로 표현된다. 예를 들면, 26은 52과 12의 합이다; 또한 42 + 32 + 1

www.acmicpc.net


문제

라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다. 어떤 자연수는 복수의 방법으로 표현된다. 예를 들면, 26은 5^2과 1^2의 합이다; 또한 4^2 + 3^2 + 1^2으로 표현할 수도 있다. 역사적으로 암산의 명수들에게 공통적으로 주어지는 문제가 바로 자연수를 넷 혹은 그 이하의 제곱수 합으로 나타내라는 것이었다. 1900년대 초반에 한 암산가가 15663 = 125^2 + 6^2 + 1^2 + 1^2라는 해를 구하는데 8초가 걸렸다는 보고가 있다. 좀 더 어려운 문제에 대해서는 56초가 걸렸다: 11339 = 105^2 + 15^2 + 8^2 + 5^2.

자연수 n이 주어질 때, n을 최소 개수의 제곱수 합으로 표현하는 컴퓨터 프로그램을 작성하시오.

입력

입력은 표준입력을 사용한다. 입력은 자연수 n을 포함하는 한 줄로 구성된다. 여기서, 1 ≤ n ≤ 50,000이다.

출력

출력은 표준출력을 사용한다. 합이 n과 같게 되는 제곱수들의 최소 개수를 한 줄에 출력한다.

예제 입력 :

25

예제 출력 : 

1

코드

import sys
import math
input = sys.stdin.readline

num = int(input())

def dp(num):
    if int(math.sqrt(num)) == math.sqrt(num):
        return 1
    for i in range(1, int(math.sqrt(num))+1):
        if int(math.sqrt(num-math.pow(i, 2))) == math.sqrt(num-math.pow(i, 2)):
            return 2
    for i in range(1, int(math.sqrt(num))+1):
        for j in range(1, int(math.sqrt(num-math.pow(i, 2)))+1):
            if int(math.sqrt(num-math.pow(i, 2)-math.pow(j, 2))) == math.sqrt(num-math.pow(i, 2)-math.pow(j, 2)):
                return 3
    return 4

print(dp(num))

+TMI

DP 파트는
1학년 때 피보나치수열 이런거 해본거 말고는 처음이라
살짝 난감했다..

이거 시간이 0.5초인거보면
하나하나 다 찾다보면 시간 초과 금방일텐데.. 하며 고민하다가
종이에 규칙 찾으려고 용을 썼는데
기본 DP문제들은 다 점화식 사용해서 하는 것 같아서
그거에 맞춰서 하려고 했더니
씁 어차피 다 훑어야하는 알고리즘밖에 생각이 나지 않았다ㅠㅠ

사실 문제를 제대로 안읽고
예시만 보느라
가장 중요한 문장인
'라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다.'
부분을 못봤다ㅠㅠ

봤어도 못맞췄을지도? ㅎ

아무튼 어쩔 수 없이..
구글...의..힘...을...빌....렸...........다...........
후 자존심 상해 쒸ㅠ

그래도 어쩔 수 없지! 
오늘이 처음이니까 그러겠지!? ㅎ

그래서 구글의 힘을 받아 사용한 방법은
1. 입력받은 수 N의 제곱근이 정수라면!
하나의 수의 제곱으로 표현할 수 있으니 1이다!
(예 : 25, 36, 49 등)

2. N에서 i의 제곱을 뺀 값의 제곱근이 정수라면!
2이다!!
(예 : 29 -> 29 - 25 = 4 의 제곱근이 2이므로 29는 5제곱 + 2제곱 => 2이다)

3. N에서 i의 제곱과 j의 제곱을 뺀 값의 제곱근이 정수라면!
3이다!!
(예 : 30 -> 30 - 25 - 4 = 1의 제곱근이 1이므로 30은 5제곱 + 2제곱 + 1제곱 => 3이다)

4. 그 외의 경우에는 4이다.

이런식으로 문제를 해결하였다.
사실 이것도 숫자가 크고 3이나 4까지 가게되면 for문을 꽤 쓰기 때문에 괜찮을까 싶었는데
통과된 것을 보면 제곱근이라 엄청 크진 않은가보다(?)

지금까지 bfs, 문자열 밖에 안해보긴했지만
DP가 가장 어려운 것 같다.

규칙찾기 연습을 더 해야겠다ㅠㅠ
화이팅!

반응형

관련글 더보기

댓글 영역