코딩테스트/C++

[백준 BOJ] 2239번 - 스도쿠 (C++)

최-코드 2024. 2. 8. 22:37

2239번: 스도쿠 (acmicpc.net)

 

2239번: 스도쿠

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

www.acmicpc.net

81자리의 수가 제일 작은 스도쿠를 만들어서 출력하는 문제이다. 81자리의 수란

이를 143628579572139....854396127로 만든 것을 의미한다.

이 문제는 백트래킹으로 풀었다. 0이 위치한 좌표를 저장한다음 이에 대해 백트래킹을 돌렸다. 이 때 가장 작게 만들려면 맨왼쪽 위의 0부터 차례대로 1부터 9까지의 값을 넣어주면서 스도쿠가 만들어지는지 보면 된다.

#include <iostream>
#include <algorithm>
#include <memory.h>
#include <vector>

using namespace std;

int board[9][9];
vector<pair<int, int>> zero;

bool check(int n, int i, int j)
{
    for (int p = 0; p < 9; p++)
    {
        if (p != j)
            if (board[i][p] == n)
                return false;
        if (p != i)
            if (board[p][j] == n)
                return false;
    }
    int x = (i / 3) * 3;
    int y = (j / 3) * 3;
    for (int p = x; p < x + 3; p++)
    {
        for (int q = y; q < y + 3; q++)
        {
            if (p != i && q != j)
            {
                if (board[p][q] == n)
                    return false;
            }
        }
    }
    return true;
}

bool finish = false;
void back(int n)
{
    if (finish)
        return;
    if (n == zero.size())
    {
        finish = true;
    }
    else
    {
        for (int i = 1; i <= 9; i++)
        {
            if (check(i, zero[n].first, zero[n].second))
            {
                board[zero[n].first][zero[n].second] = i;
                back(n + 1);
                if (finish)
                    return;
                board[zero[n].first][zero[n].second] = 0;
            }
        }
    }
}

int main()
{
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
        {
            scanf("%1d", &board[i][j]);
            if (board[i][j] == 0)
            {
                zero.emplace_back(i, j);
            }
        }
    }
    back(0);
    int en = 8;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
        {
            cout << board[i][j];
        }
        cout << '\n';
    }
    return 0;
}