반응형
문제 설명
algospot.com :: PICNIC
소풍 문제 정보 문제 안드로메다 유치원 익스프레스반에서는 다음 주에 율동공원으로 소풍을 갑니다. 원석 선생님은 소풍 때 학생들을 두 명씩 짝을 지어 행동하게 하려고 합니다. 그런데 서로
algospot.com
- 학생의 수(n), 친구 쌍의 수(m), 서로 친구인 두 학생의 번호(총 2 * m 개)가 주어진다.
=> 친구인 학생끼리 짝을 지어줄 수 있는 경우의 수 출력하기
문제 풀이
이 문제는 n명의 학생을 2명씩 짝짓는 조합 개수 구하기 문제이다.
그러나, 아무 조합이 가능한 것이 아니라 짝지어진 두 명이 친구관계여야 한다.
따라서, 짝을 지어줄 때 친구인 두 명을 짝지어주면 된다!
짝을 지어야 하는 아이(index)정보를 받는 재귀함수를 이용해 이 문제를 해결했다.
짝을 지어야 하는 아이와 친구관계인 아이들끼리 묶고,
그 남은 아이들끼리 다시 친구를 묶는 과정을 재귀로 반복한다.
그 과정에서
끝에 도달하면 성공하는 경우를 나타내는 1을 반환,
이미 index 이전의 경우에서 index와 짝이 지어진 경우라면 다음 아이를 탐색,
하는 기저 조건과 예외 조건을 추가했다.
문제 풀이 코드
#include <iostream>
#include <string.h>
using namespace std;
bool friends[10][10]; // [a][b] : a와 b가 친구인지 저장하는 배열
bool alreadyHaveMate[10]; // canMate에서 짝지어졌는지 상태 여부를 저장하는 배열
int C, n, m;
int canMate(int index) {
// 끝까지 온 경우(기저조건)
if (index == n) return 1;
// index가 이미 짝을 찾은 경우
if (alreadyHaveMate[index])
return canMate(index + 1);
// 경우의 수 세기
int cnt = 0;
// index 다음부터 스캔하면서 친구를 만들 수 있는지 확인
for (int i = index + 1; i < n; ++i) {
// i가 index와 친구이면서, 짝을 찾지 않은 경우라면
if (friends[index][i] && !alreadyHaveMate[i]) {
alreadyHaveMate[index] = alreadyHaveMate[i] = true;
cnt += canMate(index + 1);
alreadyHaveMate[index] = alreadyHaveMate[i] = false;
}
}
return cnt;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> C;
for (int tc = 0; tc < C; ++tc) {
// friends 배열 초기화
memset(friends, false, sizeof(friends));
// input, friends 표시
cin >> n >> m;
for (int i = 0; i < m; ++i) {
int f1, f2;
cin >> f1 >> f2;
friends[f1][f2] = true;
friends[f2][f1] = true;
}
cout << canMate(0) << endl;
}
return 0;
}
반응형
'알고리즘 문제풀이 > 알고리즘 문제해결전략' 카테고리의 다른 글
8.2_와일드 카드_WILDCARD (0) | 2023.02.12 |
---|---|
7.3_울타리 잘라내기_FENCE (0) | 2023.02.08 |
7.2_쿼드 트리 뒤집기_QUADTREE (0) | 2023.02.07 |
6.8_시계 맞추기_CLOCKSYNC (0) | 2023.01.20 |
6.5_게임판 덮기_BOARDCOVER (0) | 2023.01.13 |