백설 공주와 일곱 난쟁이

조소복·2022년 8월 11일
0
post-custom-banner

문제

매일 매일 일곱 난쟁이는 광산으로 일을 하러 간다. 난쟁이가 일을 하는 동안 백설공주는 그들을 위해 저녁 식사를 준비한다. 백설공주는 의자 일곱개, 접시 일곱개, 나이프 일곱개를 준비한다.

어느 날 광산에서 아홉 난쟁이가 돌아왔다. (왜 그리고 어떻게 아홉 난쟁이가 돌아왔는지는 아무도 모른다) 아홉 난쟁이는 각각 자신이 백설공주의 일곱 난쟁이라고 우기고 있다.

백설공주는 이런 일이 생길 것을 대비해서, 난쟁이가 쓰고 다니는 모자에 100보다 작은 양의 정수를 적어 놓았다. 사실 백설 공주는 공주가 되기 전에 매우 유명한 수학자였다. 따라서, 일곱 난쟁이의 모자에 쓰여 있는 숫자의 합이 100이 되도록 적어 놓았다.

아홉 난쟁이의 모자에 쓰여 있는 수가 주어졌을 때, 일곱 난쟁이를 찾는 프로그램을 작성하시오. (아홉 개의 수 중 합이 100이 되는 일곱 개의 수를 찾으시오)

입력

총 아홉개 줄에 1보다 크거나 같고 99보다 작거나 같은 자연수가 주어진다. 모든 숫자는 서로 다르다. 또, 항상 답이 유일한 경우만 입력으로 주어진다.

출력

일곱 난쟁이가 쓴 모자에 쓰여 있는 수를 한 줄에 하나씩 출력한다.

예제 입력 1

7
8
10
13
15
19
20
23
25

예제 출력 1

7
8
10
13
19
20
23

예제 입력 2

8
6
5
1
37
30
28
22
36

예제 출력 2

8
6
5
1
30
28
22

문제 풀이

import java.util.Scanner;

public class Main {
	static boolean[] check;
	static int[] arr;
	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		
		arr=new int[9];
		check=new boolean[9];
		
		for(int i=0;i<9;i++) {
			arr[i]=sc.nextInt();
		}
		
		sub(0);
	}

	private static void sub(int cnt) {
		if(cnt==9) {
			int sum=0;
			int count=0;
			for(int i=0;i<9;i++) {
				if(check[i]) {
					count++;
					sum+=arr[i];
				}
			}
			
			if(sum==100 && count==7) {
				for(int i=0;i<9;i++) {
					if(check[i]) {
						System.out.println(arr[i]);
					}
				}
			}
			return;
		}
		
		check[cnt]=true;
		sub(cnt+1);
		
		check[cnt]=false;
		sub(cnt+1);
	}
}

부분집합을 이용한 문제이다.

9명의 난쟁이들 중 7명의 진짜 난쟁이를 뽑는 문제로 7명을 선택한 후 모자에 쓰여져 있는 숫자의 합이 100인 경우를 찾으면 된다.

선택한 난쟁이는 check라는 boolean 타입에 넣어두고 하나씩 체크하여 7명이 됐고, 숫자의 합이 100인 경우 답을 출력하면된다.


직접 부분집합 알고리즘을 짜는 연습을 할 수 있었던 문제이다. 해당 숫자를 선택해서 부분집합을 구하는 경우, 해당 숫자를 선택하지 않고 부분집합을 구하는 경우를 재귀호출로 구한다고 생각하면 쉽게 짤 수 있는 로직이었다.

profile
개발을 꾸준히 해보자
post-custom-banner

0개의 댓글