이 영역을 누르면 첫 페이지로 이동
hoonDEV 블로그의 첫 페이지로 이동

hoonDEV

페이지 맨 위로 올라가기

hoonDEV

BOJ 6603 - 로또 문제풀이

  • 2020.03.30 19:10
  • 알고리즘/문제풀이

문제를 읽고 이해하기

독일 로또는 {1, 2, ..., 49}에서 수 6개를 고른다.

 

로또 번호를 선택하는데 사용되는 가장 유명한 전략은 49가지 수 중 k(k>6)개의 수를 골라 집합 S를 만든 다음 그 수만 가지고 번호를 선택하는 것이다.

 

예를 들어, k=8, S={1,2,3,5,8,13,21,34}인 경우 이 집합 S에서 수를 고를 수 있는 경우의 수는 총 28가지이다. ([1,2,3,5,8,13], [1,2,3,5,8,21], [1,2,3,5,8,34], [1,2,3,5,13,21], ..., [3,5,8,13,21,34])

 

집합 S와 k가 주어졌을 때, 수를 고르는 모든 방법을 구하는 프로그램을 작성하시오.

 

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있다.

첫 번째 수는 k (6 < k < 13)이고, 다음 k개 수는 집합 S에 포함되는 수이다. S의 원소는 오름차순으로 주어진다.

 

입력의 마지막 줄에는 0이 하나 주어진다.

 

출력

각 테스트 케이스마다 수를 고르는 모든 방법을 출력한다. 이때, 사전 순으로 출력한다.

각 테스트 케이스 사이에는 빈 줄을 하나 출력한다.

 

재정의와 추상화

이 문제를 처음 보자마자 C++ STL의 Permutation 관련 함수들이 떠올랐다. 입력받은 k개의 수 중에서 6개를 뽑는 조합의 수를 만드는 것이니, k개의 원소가 오름차순으로 정렬된 vector와, 1이 6개 0이 k - 6개가 순차적으로 들어가있는 vector를 통해 구현할 수 있다.

 

아래 예시를 보면 이해가 될 것이다!

테스트 케이스에서 주어진 k = 7, v = [ 1, 2, 3, 4, 5, 6, 7 ]을 이용할 때, 우리는 6개를 뽑는 것이기 때문에 1이 6개, 0이 1개(k - 6)가 포함된 벡터 ind = [ 1, 1, 1, 1, 1, 1, 0 ]을 이용한다.

 

1과 0으로 이루어진 벡터를 next_permutation() 함수를 이용한다.

 

[ 1, 1, 1, 1, 1, 1, 0 ] -> [ 1, 1, 1, 1, 1, 0, 1 ] -> [ 1, 1, 1, 1, 0, 1, 1 ] -> [ 1, 1, 1, 0, 1, 1, 1 ] -> [ 1, 1, 0, 1, 1, 1, 1 ] ...

 

v[ind에서 1에 해당하는 곳의 인덱스]만 출력하고, v[ind에서 0에 해당하는 곳의 인덱스]는 출력하지 않으면 된다.

 

따라서, 8개의 원소를 가지는 집합에서 6개를 고르는 방법은 아래와 같이 표현 가능하다.

ind = [ 1, 1, 1, 1, 1, 1, 0 ] -> [ 1, 1, 1, 1, 1, 0, 1 ] -> [ 1, 1, 1, 1, 0, 1, 1 ] -> [ 1, 1, 1, 0, 1, 1, 1 ] -> [ 1, 1, 0, 1, 1, 1, 1 ] ...

   v = [ 1, 2, 3, 4, 5, 6, 7 ] -> [ 1, 2, 3, 4, 5, 6, 7 ] -> [ 1, 2, 3, 4, 5, 6, 7 ] -> [ 1, 2, 3, 4, 5, 6, 7 ] -> [ 1, 2, 3, 4, 5, 6, 7 ]

 

C++ STL의 next_permutation()을 이용한 방법 외에도 DFS와 백트래킹을 이용한 방법도 있다.

 

코드 작성

// C++ STL Permutation 관련 함수를 이용한 방법

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int k;
    while (cin >> k && k) {
        vector<int> v;
        vector<int> ind;

        if (k == 0)
            break;

        for (int i = 0; i < k; i++) {
            int temp;
            cin >> temp;
            v.push_back(temp);
        }

        for (int i = 0; i < 6; i++)
            ind.push_back(1);

        for (int i = 0; i < k - 6; i++)
            ind.push_back(0);

        do {
            for (int i = 0; i < ind.size(); i++) {
                if (ind[i])
                    cout << v[i] << ' ';
            }
            cout << '\n';
        } while (prev_permutation(ind.begin(), ind.end()));

        v.clear();
        ind.clear();
        cout << '\n';
    }
    return 0;
}

// DFS와 백트래킹을 이용한 방법

#include <iostream>
#include <vector>
using namespace std;

vector<int> numbers;
vector<int> lottos;

int n;

void dfs(int start, int count) {
    if (count == 6) {
        for (int i = 0; i < 6; i++)
            cout << lottos[i] << ' ';
        cout << '\n';
        return;
    }

    for (int i = start; i < n; i++) {
        lottos.push_back(numbers[i]);
        dfs(i + 1, count + 1);
        lottos.pop_back();
    }
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    while (cin >> n && n) {
        for (int i = 0; i < n; i++) {
            int temp;
            cin >> temp;
            numbers.push_back(temp);
        }

        dfs(0, 0);
        numbers.clear();
        lottos.clear();
        cout << '\n';
    }
    return 0;
}

'알고리즘 > 문제풀이' 카테고리의 다른 글

BOJ 17839 - Baba is Rabbit 문제풀이  (0) 2020.03.31
BOJ 1929 - 소수 구하기 문제풀이  (0) 2020.03.30
BOJ 1697 - 숨바꼭질 문제풀이  (0) 2020.03.30
BOJ 1057 - 토너먼트 문제풀이  (0) 2020.03.30
BOJ 2293 - 동전 1 문제풀이  (0) 2020.03.27

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • BOJ 17839 - Baba is Rabbit 문제풀이

    BOJ 17839 - Baba is Rabbit 문제풀이

    2020.03.31
  • BOJ 1929 - 소수 구하기 문제풀이

    BOJ 1929 - 소수 구하기 문제풀이

    2020.03.30
  • BOJ 1697 - 숨바꼭질 문제풀이

    BOJ 1697 - 숨바꼭질 문제풀이

    2020.03.30
  • BOJ 1057 - 토너먼트 문제풀이

    BOJ 1057 - 토너먼트 문제풀이

    2020.03.30
다른 글 더 둘러보기

정보

hoonDEV 블로그의 첫 페이지로 이동

hoonDEV

  • hoonDEV의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그

카테고리

  • 분류 전체보기 (91)
    • 일상 (13)
      • 후기 (1)
      • 계획 (11)
    • 공지사항 (1)
    • 알고리즘 (54)
      • 문제풀이 (53)
      • 이론 (1)
    • 공부 (19)
      • React (0)
      • Angular (5)
      • Java (3)
      • C, C++ (3)
      • JavaScript (6)
      • WEB (2)
    • 디자인 (1)
      • UI, UX (1)
    • 개발 (0)
      • boom (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • dp
  • es6
  • javascript
  • 알고리즘
  • 이분탐색
  • 백준
  • 그리디
  • 문제풀이

나의 외부 링크

정보

훈개발자의 hoonDEV

hoonDEV

훈개발자

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © 훈개발자. Designed by Fraccino.

티스토리툴바