문제 링크

dfs나 bfs로 풀 수 없는 문제로 n = 25, m = 7

n!(n−m)!∗m!=480700

임을 활용하여 제한된 시간 내로 전수 조사하여 풀 수 있다.

생성된 숫자의 연결을 확인하여 풀 수 있었다.

#include <bits/stdc++.h>

using namespace std;

int n[7], ans;
string d;

int isConnected() {
    int t[5][5], v[5][5], r = 0, c, cnt = 0;
    int rD[] = { -1, 1, 0, 0 };
    int cD[] = { 0, 0, -1, 1 };

    memset(t, 0, sizeof(t));
    memset(v, 0, sizeof(v));
    for (int i = 0; i < 7; i++) {
        r = (n[i] != 0) ? (n[i] / 5) : 0;
        c = n[i] % 5;
        t[r][c] = 1;
    }

    for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++) {
        queue<pair<int, int>> q;
        if (t[i][j]) {
            q.push(make_pair(i, j));
            v[i][j] = 1;
            while (!q.empty()) {
                cnt++;
                int row = q.front().first;
                int col = q.front().second;
                q.pop();
                for (int i = 0; i < 4; i++) {
                    int nRow = row + rD[i];
                    int nCol = col + cD[i];
                    if (nRow < 0 || nCol < 0 || nRow >= 5 || nCol >= 5) continue;
                    if (v[nRow][nCol] || !t[nRow][nCol]) continue;
                    q.push(make_pair(nRow, nCol));
                    v[nRow][nCol] = 1;
                }
            }
            if (cnt == 7)
                return 1;
            else
                return 0;
        }
    }
    return 0;
}

int chk() {
    int sCnt = 0;
    for (int i = 0; i < 7; i++) {
        if (d[n[i]] == 'S')
            sCnt++;
    }
    if (sCnt >= 4) {
        if (isConnected()) {
            return 1;
        }
    }
    return 0;
}

void solve(int st, int d) {
    if (d == 7) {
        if (chk()) {
            ans++;
        }
        return;
    }

    for (int i = st; i < 25; i++) {
        n[d] = i;
        solve(i + 1, d + 1);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string z;
    for (int i = 0; i < 5; i++) {
        cin >> z;
        d += z;
    }

    solve(0, 0);

    cout << ans << "\n";
}

다른 사람 풀이

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

char A[7][7];
int ans, d[4] = { 0,0,1,-1 };
bool chk[7][7], visited[7][7];

void dfs(int x, int y) {
    visited[x][y] = 1;
    for (int i = 0; i < 4; i++) {
        int xx = x + d[i], yy = y + d[3 - i];
        if (xx < 1 || yy < 1 || xx > 5 || yy > 5 || !chk[xx][yy] || visited[xx][yy]) continue;
        dfs(xx, yy);
    }
}

bool ok() {
    int cnt = 0;
    memset(visited, 0, sizeof(visited));
    for (int i = 1; i <= 5; i++) for (int j = 1; j <= 5; j++) {
        if (chk[i][j] && !visited[i][j]) dfs(i, j), cnt++;
    }
    if (cnt > 1) return 0;
    int c1 = 0, c2 = 0;
    for (int i = 1; i <= 5; i++) for (int j = 1; j <= 5; j++) if (chk[i][j]) {
        if (A[i][j] == 'S') c1++;
        else c2++;
    }
    return c1 > 3;
}

void f(int x, int y) {
    if (y > 7) return;
    if (x == 25) {
        if (y == 7) ans += ok();
        return;
    }
    f(x + 1, y);
    chk[x / 5 + 1][x % 5 + 1] = 1;
    f(x + 1, y + 1);
    chk[x / 5 + 1][x % 5 + 1] = 0;
}

int main() {
    for (int i = 1; i <= 5; i++) scanf("%s", A[i] + 1);
    f(0, 0);
    printf("%d\n", ans);
}

댓글남기기