본문 바로가기
PS 문제 풀이/Baekjoon

[BOJ] 백준 2309 일곱 난쟁이

by 까망 하르방 2021. 7. 28.
반응형

출처https://www.acmicpc.net/problem/2309  

Approach

완전탐색 유형 문제이다.

 

완전탐색 기법이란?

가능한 모든 값을 대입해보는 무식한(?) 방법에 해당된다. 문제 내용 속에서 특정 규칙을 찾아서 모든 Case를 대입해보지 않고도 풀리는 경우도 있지만 충분한 제한 공간과 시간이 주어진다면 

zoosso.tistory.com

- 9명의 난쟁이 중에서 7명 선택해서 그 숫자의 합 = 100 이면 된다.

- 출력 시, 오름차순으로 해야 하기에 선택 전/후로 오름차순 정렬시켜준다.

 

▶ 순열과 조합  

 

순열과 조합 (백준 N과 M 시리즈)

순열과 조합 순열(Permutation) / 조합(Combination)에서 개수를 구하는 경우에는 ▶ P(n, r) = n × (n - 1) × (n - 2) × ... × (n - r - 1) = n! / (n - r)! 상황에 따라서는 주어지는 Data가 나올 수..

zoosso.tistory.com

▶ 중복 없는 Input Data에 중복없이 선택

 

[BOJ] 백준 15655 N과 M(6)

출처: https://www.acmicpc.net/problem/15655 Approach ▶ 순열과 조합 (백준 N과 M 시리즈) 순열과 조합 (백준 N과 M 시리즈) 순열과 조합 순열(Permutation) / 조합(Combination)에서 개수를 구하는 경우에..

zoosso.tistory.com

 

제출 코드 (조합 Ver.)

#include <stdio.h>

const int N = 9;
const int PICK = 7;
const int TOTAL = 100;
int ans[N], arr[N], trr[N], sum;
bool flag, visited[N];

void input()
{
    for (int i = 0; i < N; ++i)
    {
        scanf("%d", &arr[i]);
    }
}

void mergeSort(int start, int end) {
    // 0. base condition
    if (start >= end) return;
    // 1. divide
    int mid = (start + end) / 2;
    // 2. conquer
    mergeSort(start, mid);
    mergeSort(mid + 1, end);
    // 3. merge
    int i = start, j = mid + 1, k = start;
    while (i <= mid && j <= end) {
        if (arr[i] < arr[j])
            trr[k++] = arr[i++];
        else
            trr[k++] = arr[j++];
    }
    while (i <= mid) trr[k++] = arr[i++];
    while (j <= end) trr[k++] = arr[j++];
    // 4. copy
    for (i = start; i <= end; ++i) {
        arr[i] = trr[i];
    }
}

void DFS(int idx, int depth) {
    if (flag)
    {
        return;
    }

    if (depth == PICK)
    {
        sum = 0;
        for (int i = 0; i < PICK; ++i)
        {
            sum += ans[i];
        }

        if (sum == TOTAL)
        {
            flag = true;
            for (int i = 0; i < PICK; ++i)
            {
                printf("%d\n", ans[i]);
            }
        }
        return;
    }

    for (int i = idx; i < N; ++i)
    {
        if (visited[i]) continue;
        
        visited[i] = true;
        ans[depth] = arr[i];

        DFS(i, depth + 1);

        visited[i] = false;
        ans[depth] = 0;
    }
}

int main() {
    // freopen("input.txt", "r", stdin);
    input();
    mergeSort(0, N - 1);
    DFS(0, 0);
}

 

제출 코드 (C++)

또 다른 방법으로는 9명 중에서 두명을 제외하는 것을 생각해볼 수 있다.

9C7 = 9C2 = 36 이다.

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 9;
const int TOTAL = 100;

int arr[N], sum;

void output(int tg1, int tg2)
{
    for (int i = 0; i < N; ++i)
    {
        if (tg1 == i || tg2 == i)
            continue;


        printf("%d\n", arr[i]);
    }
}

int main()
{
    // freopen("input.txt", "r", stdin);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &arr[i]);
        sum += arr[i]; // 9명의 키
    }
    
    // 오름차순 정렬
    sort(arr, arr + N);

    for (int tg1 = 0; tg1 < N; ++tg1)
    {
        for (int tg2 = tg1 + 1; tg2 < N; ++tg2)
        {
            if (sum - (arr[tg1] + arr[tg2]) == TOTAL)
            {
                output(tg1, tg2);
                return 0;
            }
        }
    }
}

 

제출 코드 (Java)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int[] arr = new int[9];
		
		for (int i = 0; i < arr.length; i++) {
			arr[i] = Integer.parseInt(sc.next());
		}
		Arrays.sort(arr);
		int result = 0;
		int no1 = 0, no2 = 0;
		outer:
		for (int i = 0; i < arr.length-1; i++) {
			int end = arr.length-1;
			
			while(true){
				if(i == end)
					break;
				int sum = 0;
				for(int j=0; j < arr.length; j++){
					if(j != i && j != end){
						sum += arr[j];
					}
				}
				if(sum == 100){
					no1 = i;
					no2 = end;
					break outer;
				}
				end--;
			}
		}
		
		for (int i = 0; i < arr.length; i++) {
			if(i != no1 && i != no2){
				System.out.println(arr[i]);
			}
		}
	}
}
반응형

'PS 문제 풀이 > Baekjoon' 카테고리의 다른 글

[BOJ] 백준 13701 중복 제거  (0) 2021.08.02
[BOJ] 백준 2210 숫자판 점프  (0) 2021.07.29
[BOJ] 백준 2231 분해합  (0) 2021.07.27
[BOJ] 백준 3085 사탕 게임  (0) 2021.07.24
[BOJ] 백준 10448 유레카 이론  (0) 2021.07.23

댓글