P.6603 로또

castlehi·2022년 3월 17일
0

CodingTest

목록 보기
38/67
post-thumbnail

6603 로또

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초 128 MB39030217761487754.653%

문제

독일 로또는 {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이 하나 주어진다.

출력

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

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

예제 입력 1

7 1 2 3 4 5 6 7
8 1 2 3 5 8 13 21 34
0

예제 출력 1

1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 6 7
1 2 3 5 6 7
1 2 4 5 6 7
1 3 4 5 6 7
2 3 4 5 6 7

1 2 3 5 8 13
1 2 3 5 8 21
1 2 3 5 8 34
1 2 3 5 13 21
1 2 3 5 13 34
1 2 3 5 21 34
1 2 3 8 13 21
1 2 3 8 13 34
1 2 3 8 21 34
1 2 3 13 21 34
1 2 5 8 13 21
1 2 5 8 13 34
1 2 5 8 21 34
1 2 5 13 21 34
1 2 8 13 21 34
1 3 5 8 13 21
1 3 5 8 13 34
1 3 5 8 21 34
1 3 5 13 21 34
1 3 8 13 21 34
1 5 8 13 21 34
2 3 5 8 13 21
2 3 5 8 13 34
2 3 5 8 21 34
2 3 5 13 21 34
2 3 8 13 21 34
2 5 8 13 21 34
3 5 8 13 21 34

코드

import java.io.*;
import java.util.Arrays;

public class P_6603 {

    static int              k;
    static int[]            perm;
    static int[]            lotto_num;
    static BufferedWriter   bw;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));

        while (true) {
            int[] info = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();

            k = info[0];
            if (k == 0) break;

            perm = Arrays.copyOfRange(info, 1, info.length);
            lotto_num = new int[6];

            find_lotto(0, 0);
            bw.newLine();
        }
        bw.flush();
    }

    public static void find_lotto(int pos, int idx) throws IOException {
        if (pos == 6) {
            for (int num : lotto_num) bw.write(num + " ");
            bw.newLine();
        }
        else {
            for (int i = idx; i < k; i++) {
                lotto_num[pos] = perm[i];
                find_lotto(pos + 1, i + 1);
            }
        }
    }
}

코드 설명

백트래킹을 이용했다.

find_lotto 함수의 첫 번째 인자는 lotto_num 배열에서 현재 참조하고 있는 부분 (로또 번호를 넣을 부분)을 의미하고 두 번째 인자인 idx는 주어진 lotto 번호들 중 어느 번호를 넣어야 하는 지를 의미한다.

pos가 6이 되면 lotto_num을 모두 채운 것이 되므로 버퍼에 쓰게 된다.
pos가 6이 아닐 때는 아직 lotto_num을 채우지 않았으므로 for문을 들어가는데 for문의 첫 시작은 인자로 넘겨받은 idx부터 시작을 한다. 그리고 이 idx는 find_lotto를 호출할 때마다 i + 1로 갱신되어 같은 번호를 중복해서 lotto_num에 넣지 않도록 했다.

for문에서 lotto_num의 한 부분을 채우게 되면 바로 가지 수를 늘려 나가도록 설계를 했다.

profile
Back-end Developer

0개의 댓글