백준 2580 스도쿠 (C++)

안유태·2022년 9월 16일
0

알고리즘

목록 보기
39/239

2580번: 스도쿠

생각보다 어려웠던 문제였다. 9 X 9 사이즈 스도쿠를 풀면 되는 문제이다. 일단 0에 해당하는 좌표를 벡터에 저장을 해두고 백트래킹을 해주었다. 여기서 포인트가 두가지가 있다. 첫번째는 exit(0)이다. 문제에서 답이 여러가지가 나올 경우 한가지만 출력을 하라고 제시되어 있기 때문에 한가지만을 출력하고 exit(0)으로 종료를 해준다. 두번째는 if (j == 9) return;이다. 이부분을 안해주게 되면 첫 재귀에 모든 0에 접근을 하게 되고 그렇게되면 중간 중간 0이 섞인채로 첫 재귀를 통한 값이 출력되고 exit(0)에 의해 종료되게 된다.
질문 게시판을 통해 아이디어를 얻어 풀 수 있었다. 어려웠다.



#include <iostream>
#include <vector>

using namespace std;

int A[9][9];
vector<pair<int, int>> v;

bool isRight(int y, int x, int value) {
    for (int i = 0; i < 9; i++) {
        if (A[y][i] == value) return false;
        if (A[i][x] == value) return false;
    }

    int tmp_y = (y / 3) * 3;
    int tmp_x = (x / 3) * 3;

    for (int i = tmp_y; i < tmp_y + 3; i++) {
        for (int j = tmp_x; j < tmp_x + 3; j++) {
            if (A[i][j] == value) return false;
        }
    }

    return true;
}

void sudoku(int depth) {
    if (v.size() == depth) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                cout << A[i][j] << " ";
            }
            cout << endl;
        }

        exit(0);
    }

    for (int i = depth; i < v.size(); i++) {
        int y = v[i].first;
        int x = v[i].second;

        for (int j = 1; j < 10; j++) {
            if (isRight(y, x, j)) {
                A[y][x] = j;
                sudoku(depth + 1);
                A[y][x] = 0;
            }

            if (j == 9) return;
        }
    }
}

void solution() {
    sudoku(0);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            cin >> A[i][j];
            if (A[i][j] == 0) {
                v.push_back({ i,j });
            }
        }
    }

    solution();

    return 0;
}
profile
공부하는 개발자

0개의 댓글