[실전 문제] 제곱수의 합
2021. 2. 25. 14:41ㆍ코딩 테스트/실전 문제
1. 문제
숫자 N을 제곱수의 합으로 표현하고자 할 때, 사용해야 하는 제곱 수의 최소 개수를 출력하는 프로그램을 작성하시오. 예를 들어, 숫자 45를 제곱수의 합으로 표현하고자 할 때 필요한 제곱 수의 최소 개수는 2개이며, 이는 다음과 같다.
45 = 3^2 + 6^2
입력
첫 번째 줄에 N이 주어진다. ( 1 ≤ N ≤ 100,000 )
출력
필요한 제곱 수의 최소 개수를 출력한다.
예제 입력
case 1) 45
case 2) 38
예제 출력
case 1) 2
case 2) 3
2. 풀이
이 문제는 점화식을 만드는것이 핵심이다. 점화식을 구하는 순서는 다음과 같다.
- T(n) = T(a^2 + b^2 + c^2) = 3
- T(n-a^2) = T(b^2 + c^2) = 2
- 즉, T(n) = T(n-x^2) + 1
T(8) 일 경우,
- 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 8개
- 2^2 + 1 + 1 + 1 + 1 = 5개
- 2^2 + 2^2 = 2개
일 때, 이 중 가장 최소가 되는 2가 답이 된다.
이 점을 이용하여 코드를 작성하면 다음과 같다.
import java.io.*;
public class Main {
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int n = Integer.parseInt(br.readLine());
int[] dp = new int[n+1];
int sqrtX = (int) Math.sqrt(n); // dp[n] = dp[n-x^2] + 1
for(int i = 1; i <= n; i++) {
if(i == 1) {
dp[i] = 1;
continue;
}
for(int x = 1; x <= (int)Math.sqrt(i); x++) {
if(i == x*x) dp[i] = 1;
else {
if(dp[i] > 0) dp[i] = Math.min(dp[i], dp[i - x * x] + 1); // dp[i]에 값이 있을 경우
else dp[i] = dp[i - x * x] + 1; // dp[i]에 값이 없을 경우
}
}
}
bw.write(dp[n] + "");
br.close();
bw.flush();
bw.close();
}
}
728x90
'코딩 테스트 > 실전 문제' 카테고리의 다른 글
[실전 문제] 연속 부분 최대합 L (0) | 2021.02.27 |
---|---|
[실전 문제] 자원 채취 (0) | 2021.02.27 |
[실전 문제] 직사각형배치의경우의수 (0) | 2021.02.25 |
[실전 문제] 버튼 누르기 (0) | 2021.02.25 |