티스토리 뷰

728x90

문제 링크

www.acmicpc.net/problem/1799

 

1799번: 비숍

첫째 줄에 체스판의 크기가 주어진다. 체스판의 크기는 10이하의 자연수이다. 둘째 줄부터 아래의 예와 같이 체스판의 각 칸에 비숍을 놓을 수 있는지 없는지에 대한 정보가 체스판 한 줄 단위로

www.acmicpc.net

 

풀이

1) 백트래킹을 해야 합니다. 근데 나이브하게 탐색하면 당연히 시간 초과입니다.

 

2) 우선 어떤 칸의 행, 열로 그 칸이 어떤 대각선에 속해있는지 $O(1)$로 체크할 수 있습니다.

행, 열을 $i, j$라 할 때 오른쪽 위로 가는 대각선을 보면 $(i + j)$값이 같은 칸들이 같은 대각선에 속하고, 오른쪽 아래로 가는 대각선을 보면 $(i - j)$값이 같은 칸들이 같은 대각선에 속합니다. 

다만 $(i - j)$는 음수가 될 수 있으므로 $n$을 더해 양수로 만들어줍시다.

 

 

3) 대각선 체크를 $O(1)$로 할 수 있다고 해도 모든 칸을 가로, 세로 순으로 탐색하면 경우의 수가 너무 많아집니다.

체스판을 45$^{\circ}$ 기울였다고 생각하면 대각선 순으로 탐색할 수 있습니다. 그러면 한 줄 당 하나의 칸만 선택해주면 됩니다. 이를 코드의 40번째 줄에서 처리합니다.

 

4) 이까지 했으면 백트래킹 하는 경우의 수가 $O((N!)^{2})$ 정도로 줄어들게 됩니다. 하지만 아직도 많습니다.

사실 체스판을 잘 보면, 짝수번째 대각선과 홀수번째 대각선이 독립적이라는 걸 알 수 있습니다. 즉, 짝수번 대각선에 있는 비숍은 홀수번 대각선의 비숍을 절대 잡을 수 없습니다.

 

따라서 짝수번, 홀수번 대각선을 각각 백트래킹 해주면$O(N!)$ 정도로 충분히 통과할 수 있게 됩니다.

 

 

정답 코드

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
#define ft first
#define sd second
using namespace std;
using pii = pair<int, int>;

int n;
bool chk[22];
vector<vector<pii>> p;

int go(int i) {
    if (i >= p.size()) return 0;

    int ret = 0;
    for (int j = 0; j < p[i].size(); j++) {
        auto[x, y] = p[i][j];
        if (!chk[x - y + n]) {
            chk[x - y + n] = true;
            ret = max(ret, go(i + 2) + 1);
            chk[x - y + n] = false;
        }
    }
    ret = max(ret, go(i + 2));

    return ret;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    p.resize(2 * n + 1);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int x;
            cin >> x;
            if (x == 1) p[i + j].emplace_back(i, j);
        }
    }
    cout << go(0) + go(1);
}
728x90

'알고리즘 > 문제 풀이' 카테고리의 다른 글

[BOJ] 백준 1987 알파벳  (0) 2021.03.08
[BOJ] 백준 1806 부분합  (0) 2021.03.08
[BOJ] 백준 1647 도시 분할 계획  (0) 2021.03.08
[BOJ] 백준 1644 소수의 연속합  (0) 2021.03.08
[BOJ] 백준 1562 계단 수  (0) 2021.03.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함