코딩테스트/백준
[Dev-Ping9] 백준 2231번 - 분해합 (Java)
DevPing9_
2021. 12. 14. 10:56

헐... 21등 했어요... 🥺🥺🥺

# 문제설명
[Base Description]
생성자가 여러개 있을 수 있음 -> 모든 경우를 탐색해야 한다 -> 그 중에 가장 작은수를 찾아야함
[N의 최대 값인 1백만으로 가정]
>> 찾아지는 생성자(m)은 상당히 큰 수 일 것이 자명
>> 0에서 N까지 탐색하는 방법은 상당히 비효율적
>> 일정범위 이하로는 탐색할 필요가 없을 것이 자명
[어디까지를 탐색범위로 제한할 것인가?]
>> N = m + sub(m)
>> sub(m) 은 아무리 크더라도, N의 자릿수갯수 * 9 이하
>> sub(m) 을 최대값으로 가정했을때 만족하는 m 이하로는 탐색할 필요가 없음 (반대로 말하면, 해당 m보다 큰값만 탐색하면 됨)
# 코드구현
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main{
static int ans;
public static void dfs(int n, int m){
char[] nums = String.valueOf(m).toCharArray();
if(n>nums.length*9+m) return;
int sum =m;
for(char i : nums){ // 각자릿수 합
sum+=(i-'0');
}
if(n == sum){
ans = m;
}
dfs(n,m-1);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
//n이 주어졌을때 n의 생성자.. -> m + m의 각자리수 합
//각 자릿수는 10보다 작기때문에, 자리수 갯수가 k일때, 각자릿수합은 9*k 이하
//그러니까 숫자가 큰것에서 내려가면서 탐색하면 금방찾음
//근데 가장작은 생성자를 찾아야함. 어디까지를 기준으로 잡아야하나.. n/2?
//음,,, 100이하는 풀탐색하고 그다음부터는 n/2까지 돌릴까?
//n <=1_000_000 ... -> 완전탐색시 1백만 -> 최대자릿수 7개 -> 합은 63보다 작음 -> m + sub(m)
// n= m + 최대합 ...!
dfs(n,n-1);
System.out.println(ans);
}
}
728x90