본문 바로가기

Algorithms/종만북

[종만북] 6장. 완전 탐색 (2) PICNIC

문제 바로가기: https://www.algospot.com/judge/problem/read/PICNIC

 

1. 중복된 답

아래 코드의 문제점은 중복된 답을 세는 경우를 처리하지 않은 점이다. 중복이 된 원인은 (0, 1)과 (1, 0)을 각각 다른 경우로 봤고 다른 순서로 학생들을 짝지어 주는 것도 서로 다르다고 카운트했기 때문이다. 

#include <bits/stdc++.h>
using namespace std;

int n;
bool graph[10][10]; // 최대 10

int countPairings(bool taken[10]) { // taken[i]: i번 학생이 짝을 찾은 경우 true
	// Base case: 전부 짝이 생기면 종료
	bool finished = true;
	for (int i = 0; i < n; i++) if (!taken[i]) finished = false;
	if (finished) return 1; 

	int ret = 0;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			// 친구 맺어주기
			if (!taken[i] && !taken[j] && graph[i][j]) {
				taken[i] = taken[j] = true;
				ret += countPairings(taken); // 친구 생성 후 다음 재귀 호출
				taken[i] = taken[j] = false; // i랑 j가 친구지만 서로 짝이 안지어진 경우도 고려하기 위함
			}
		}
	}
	return ret;
}

int main() {
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int c;
	cin >> c;
	while (c--) {
		int m;
		cin >> n >> m;
		
		// 무향 그래프 연결
		fill(graph[0], graph[0] + 100, 0);
		for (int i = 0; i < m; i++) {
			int a, b; cin >> a >> b;
			graph[a][b] = 1;
			graph[b][a] = 1;
		}

		bool tp[10]{ };
		cout << countPairings(tp) << "\n";
	}
}

 

2. 중복된 답 제거 

중복으로 세는 상황이 생길 때 흔히 사용하는 방법으로는 여러가지 답 중에서 사전순으로 가장 먼저 오는 답 하나만을 세는 방법이 있다. 여기선 학생들별로 우선순위를 정해서 해당 학생부터 짝을 지어주면 된다. 마침 학생들이 번호로 되어 있으므로, i를 0부터 n-1까지로 반복하다가 i번째 학생이 짝이 없으면 그 학생을 타깃으로 정하면 된다. 그 학생과 짝이 될 학생을 찾는 과정은 위와 동일하다.

int countPairings(bool taken[10]) { // taken[i]: i번 학생이 짝을 찾은 경우 true
	// 남은 학생들 중 가장 번호 빠른 학생 찾기 
	int firstFree = -1;
	for (int i = 0; i < n; i++) {
		if (!taken[i]) {
			firstFree = i; break;
		}
	}

	if (firstFree == -1) return 1; // Base Case: 모든 학생들 다 짝 지어짐

	int ret = 0;
	// firstFree 학생과 짝 지어줄 학생 찾기
	for (int pairWith = firstFree + 1; pairWith < n; pairWith++) {
		if (!taken[pairWith] && graph[firstFree][pairWith]) {
			taken[pairWith] = taken[firstFree] = true;
			ret += countPairings(taken); // 친구 생성 후 다음 재귀 호출
			taken[pairWith] = taken[firstFree] = false; // 이 둘이 서로 짝이 안지어진 경우도 고려하기 위함
		}
	}
	return ret;
}

'Algorithms > 종만북' 카테고리의 다른 글

[종만북] 6장. 완전 탐색 (1) 원소 고르기, BOGGLE  (0) 2022.01.20