Q 2309 일곱 난쟁이
💡 문제 요약 및 분석
일곱 난쟁이의 키의 합계는 100이다. 아홉 난쟁이들 중에서 키의 합이 100이 되는 조합을 하나만 찾아서 출력하면 된다.
💡 알고리즘 설계
이번에는 배열이 필요할 것 같다. 9칸짜리 배열에 난쟁이들의 키를 입력받는다. 중첩 for문을 돌면서 배열 중 2개의 값을 빼고 나머지 값을 더한다. (이렇게 하면 모든 경우의 수를 돌아볼 수 있다) 합계가 100인 조합을 찾아내면 2개 값을 remove 하고 배열을 오름차순 정렬한 후 출력하면 된다.
💡 코드
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 9; i++) {
list.add(sc.nextInt());
}
// 배열 돌면서 2개 값을 제외한 나머지를 더한 값이 100인 경우 찾기
int sum = 0;
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
for (int k = 0; k < list.size(); k++) {
if (k != i && k != j) {
sum += list.get(k);
}
}
if (sum == 100) {
List<Integer> result = new ArrayList<>();
for (int k = 0; k < list.size(); k++) {
if (k != i && k != j) {
result.add(list.get(k));
}
}
// 오름차순 정렬 후 출력
result.stream()
.sorted()
.forEach(System.out::println);
return;
} else {
sum = 0;
}
}
}
}
}
💡 틀린 부분 수정
💡 시간 복잡도, 공간 복잡도
시간 복잡도 | 공간 복잡도 |
---|---|
O(n^3) | O(n) |
⏱️ 이중 루프, 내부 루프가 총 3개 있어서 일반화하면 O(n^3) 이지만, n = 9 이므로 실제 속도는 매우 빠르다.
🧠 입력 크기에 비례하는 리스트가 있어서 공간 복잡도는 O(n) 이다.
💡 다른 풀이
지금까지는 편의상 Scanner 를 사용했지만 코테에서는 문제 풀이 속도가 미션으로 주어지는 경우도 있기에 BufferedReader 로 바꿔서 작성했다. 그리고 기존 작성한 코드가 너무 중첩문 범벅이라 좀더 단순화할 방법이 없는지 찾아보았는데 조금 더 간단한 방법의 풀이가 있어 구현해보았다. 코드가 간결해졌고 속도도 훨씬 빨라진 것을 볼 수 있다.
import java.io.*;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] ary = new int[9];
// 키를 입력받음과 동시에 전체 키를 더해둔다.
int sum = 0;
for (int i = 0; i < 9; i++) {
ary[i] = Integer.parseInt(br.readLine());
sum += ary[i];
}
br.close();
// 아홉 난쟁이 배열의 합계에서 2개를 뺀 값이 100이 되는 경우의 수를 찾는다.
for (int i = 0; i < ary.length; i++) {
for (int j = i + 1; j < ary.length; j++) {
if (sum - ary[i] - ary[j] == 100) {
ary[i] = 0;
ary[j] = 0;
// 오름차순 정렬 후 출력
Arrays.sort(ary);
for (int k = 2; k < ary.length; k++) {
System.out.println(ary[k]);
}
return;
}
}
}
}
}
💡 느낀점 및 기억할 정보
BufferedReader
Scanner 는 키보드의 키를 누르는 즉시 프로그램에 전달되지만 Buffer 를 사용하면 입력된 값을 모아다가 개행 문자를 입력하거나 버퍼가 가득 차면 프로그램에 전달한다. 때문에 Scanner 보다 빠른 속도가 강점이다. 입력은 readLine() 메서드로 이루어지는데, 이 때 리턴값은 String 이다. 그래서 형변환을 해주거나 StringTokenizer, split 등을 사용해야 한다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
int i = Integer.parseInt(br.readLine());
// StringTokenizer 를 사용하면 공백 단위로 자를 수 있다.
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Interger.parseInt(st.nextToken());
int b = Interger.parseInt(st.nextToken());
BufferedWriter
일반적으로 출력을 할 때는 System.out.print 를 사용하지만 많은 양의 출력이 필요한 경우 버퍼를 사용하는 것이 좋다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str = "출력할 문자열";
bw.write(str); // 출력
bw.newLine(); // 줄바꿈
bw.flush(); // 남아있는 데이터 전부 출력
bw.close();