Old/백준

백준 6603번 로또 // C++

mang_dev 2020. 2. 17. 21:17

문제

 

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

출력

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

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

 


 

풀이

 

입력받은 숫자를 오름차순으로 정렬하여 크기가 6인 순열로 나타내는 문제이다. 

 

C++에서는 next_permutation을 사용하여 표현이 가능하지만, 이번에는 dfs를 이용하여 문제를 풀었다.

 

주의할 점은 출력할 때 각 케이스마다 한 줄을 띄워서 구분을 해야한다!


 

코드

더보기
#include <iostream>
#include <queue>
#include <algorithm>

using namespace std;

vector<int> number;
bool visit[13];
vector<int> print;

void dfs(int start, int size);

int main() {
	int n;

	while (true) {
		cin >> n;
		if (n == 0)
			break;

		number.clear();

		for (int i = 0; i < n; i++) {
			int input;
			cin >> input;

			number.push_back(input);
			visit[i] = false;
		}

		sort(number.begin(), number.end());

		for (int i = 0; i < n; i++) {
			dfs(i, 0);
			visit[i] = false;
			print.clear();
		}

		printf("\n");
	}
}

void dfs(int start, int size) {
	visit[start] = true;
	size++;
	print.push_back(number[start]);

	if (size >= 6) {
		for (int i = 0; i < print.size(); i++) {
			printf("%d ", print[i]);
		}
		printf("\n");
		return;
	}

	for (int i = start + 1; i < number.size(); i++) {
		if (!visit[i])
			dfs(i, size);

		visit[i] = false;
		print.pop_back();
	}
}