티스토리 뷰

728x90

문제 링크

www.acmicpc.net/problem/2239

 

2239번: 스도쿠

스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다

www.acmicpc.net

 

풀이

생각 없이 풀 수 있는 백트래킹 문제입니다.

 

각 행, 열, 3*3 그룹마다 체크 배열을 만들어 두고 1~9까지의 수가 들어 있는지 비트 마스킹으로 확인합니다.

칸 $(i, j)$는 $(i/3)*3 + j/3$ 번째 그룹$(0-based)$에 포함되어있다는 것만 생각해주시면 됩니다.

 

 

정답 코드

#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using vpii = vector<pii>;

int r[10], c[10], sq[10];
int p[10][10];
const int n = 9;

int sqnum(int x, int y) {
    return (x / 3) * 3 + y / 3;
}

vpii binkan;

bool go(int idx) {
    if (idx == binkan.size()) {
        return true;
    }
    auto[x, y] = binkan[idx];
    int sqidx = sqnum(x, y);
    bool ret = false;
    for (int i = 1; i < n + 1; i++) {
        int bit = 1 << i;
        if ((r[x] & bit) || (c[y] & bit) || (sq[sqidx] & bit)) continue;
        r[x] |= bit;
        c[y] |= bit;
        sq[sqidx] |= bit;
        p[x][y] = i;
        if ((ret |= go(idx + 1))) break;
        p[x][y] = 0;
        r[x] &= ~bit;
        c[y] &= ~bit;
        sq[sqidx] &= ~bit;
    }
    return ret;
}

int main() {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%1d", &p[i][j]);
            if (p[i][j] == 0) {
                binkan.emplace_back(i, j);
                continue;
            }
            int bit = 1 << p[i][j];
            r[i] |= bit;
            c[j] |= bit;
            sq[sqnum(i, j)] |= bit;
        }
    }
    go(0);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d", p[i][j]);
        }
        puts("");
    }
}
728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함