250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 백준2251
- 중복순열
- 정올 1620
- 볼륨 만들기
- 자바 코테
- java
- 알고리즘개념
- 코테준비
- BFS
- 완전탐색
- N과M
- 주사위굴리기2
- 전화번호속의암호
- 삼성역테
- 에라토스테네스의채
- 백준15652
- 자바
- 중복조합
- 재귀함수
- 순열
- 23288
- 코테
- 파티션 크기 조정
- 백준13458
- 완탐
- Bfs와DFS
- 정보처리기사
- 알고리즘
- 백준
- D드라이브생성
Archives
- Today
- Total
뚱땅뚱땅
[문제] 백준 2231번 분해합 본문
728x90
* 출처: 백준 단계별로 풀어보기 브루트포스 편
2231번: 분해합
어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이
www.acmicpc.net
내 생각
1. 첫번째 풀이
'순열'스럽게 문제를 풀어봤다.
다만 범위를 너무 넓게 잡고, 답을 구하더라도 끝까지 탐색하기 때문에 시간이 많이 걸린다. 다른 답안에 비해 10배 이내로 걸리는 듯하다.
public class BOJ2231 {
static int N;
static int NJari;
static int numbers[];
static int answer[];
static int first = 0;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String s = in.readLine();
N = Integer.parseInt(s);
NJari = s.length();
numbers = new int[NJari]; // 자리수
answer = new int[NJari]; // 자리수
permutation(0);
if(first == 0) {
System.out.println("0");
}else {
System.out.println(arrtoNum());
}
}
static String arrtoNum() {
int tmp = 0;
for(int i =0;i<NJari;i++) {
if(answer[i] != 0) {
tmp = i;
break;
}
}
String s = "";
for(int i=tmp;i<NJari;i++) {
s+= String.valueOf(answer[i]);
}
return s;
}
static void permutation(int cnt) {
if (cnt == NJari) {
int tmp = 0;
for (int i = 0; i < NJari; i++) {
tmp += numbers[i];
tmp += numbers[i] * (int) Math.pow(10, NJari - i - 1);
}
if (tmp == N) {
first++;
if (first == 1) {
System.arraycopy(numbers, 0, answer, 0, NJari);
}
}
return;
}
for (int i = 0; i < 10; i++) {
numbers[cnt] = i;
permutation(cnt + 1);
}
}
}
2. 두번째 풀이
for문을 통한 완전 탐색. 쉽지만 이것 역시 비효율적이다.
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int result = 0;
for(int i=1;i<N;i++) {
int number = i;
int sum = 0;
while(number!=0) {
sum += number%10; // 각 자리수 합
number /= 10;
}
if(sum+i == N) {
result = i;
break;
}
}
System.out.println(result);
}
}
3. 최적화된 풀이
N의 생성자를 X라고 할 때,
N = X + (X의 각 자리 합)
=> X = N - (X의 각 자리 합)
즉, X 가 될 수 있는 최소 범위는 X의 각 자리합이 최대가 되면 된다.
N의 자릿수를 NJari라 할 때, X의 각 자리합이 최대가 되려면, NJari 자리수에다가 9로 가득 채워지면 된다.
X >= N - 9 * NJari
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int N = Integer.parseInt(s);
int NJari = s.length();
int result = 0;
for (int i = N - NJari * 9; i < N; i++) {
int num = i;
int sum = 0;
while (num != 0) {
sum += num % 10; // 각 자리수 합
num /= 10;
}
if (sum + i == N) {
result = i;
break;
}
}
System.out.println(result);
}
}
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[문제] 백준 1992번 쿼드트리 (0) | 2021.02.04 |
---|---|
[문제] 백준 15664번 N과 M(10) (0) | 2021.02.04 |
[문제] 백준 2798번 블랙잭 (0) | 2021.02.02 |
[문제] 백준 1244번 스위치 켜고 끄기 (0) | 2021.02.01 |
[문제] 백준 17478번 재귀함수가 뭔가요? (0) | 2021.02.01 |
Comments