본문 바로가기

PS

백준 BOJ 1941 C++ [소문난 칠공주]

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

char board[5][5];
bool visited[5][5];
int student_indices[25];  // S: 1, Y:0
int temp_board[5][5];
int ans;

int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};

void bfs(int x, int y) {  // 연결성 검사를 위한 bfs
    queue<pair<int, int>> q;
    visited[x][y] = true;
    q.push({x, y});
    while (!q.empty()) {
        x = q.front().first;
        y = q.front().second;
        q.pop();
        for (int k = 0; k < 4; ++k) {
            int nx = x + dx[k];
            int ny = y + dy[k];
            if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5) {
                if (temp_board[nx][ny] == 1 && !visited[nx][ny]) {
                    visited[nx][ny] = true;
                    q.push({nx, ny});
                }
            }
        }
    }
}

bool is_connected() {
    int cnt = 0;
    for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 5; ++j) {
            if (temp_board[i][j] == 1 && !visited[i][j]) {
                cnt++;
                bfs(i, j);
            }
        }
    }
    if (cnt == 1) {
        return true;
    }
    return false;  // bfs를 2번 이상 호출했다면 끊긴 것
}

void solve() {
    for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 5; ++j) {
            cin >> board[i][j];
            if (board[i][j] == 'S') {
                student_indices[5 * i + j] = 1;  // 조합을 사용하기 위해 2차원 배열의 인덱스를 1차원 배열로 다룸
            }
        }
    }
    // 25 명 중 7명을 뽑는 조합
    vector<int> selector(25, 1);
    fill(selector.begin(), selector.begin() + 7, 0);
    do {
        memset(temp_board, 0, sizeof(temp_board));
        memset(visited, false, sizeof(visited));
        int y_counts = 0;  // 조합에서 'Y'파 학생 수를 세는 변수
        for (int i = 0; i < 25; ++i) {
            if (selector[i] == 0) {  // 뽑은 학생이
                if (student_indices[i] == 0) {  // 'Y'파 인 경우
                    y_counts++;
                }
                temp_board[i / 5][i % 5] = 1;
            }
        }
        if (y_counts >= 4) {  // 'Y'파 학생이 4명 이상인 경우 해당 조합을 폐기하고 다음 조합을 뽑기 위해 넘어간다.
            continue;
        }
        if (is_connected()) {  // 조합의 학생들이 끊어지지 않고 연결되어 있다면 카운트
            ans++;
        }
    } while (next_permutation(selector.begin(), selector.end()));
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    solve();
    return 0;
}