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

위 그림은 참 잘도 스도쿠 퍼즐을 푼 경우이다. 각 행에 1부터 9까지의 숫자가 중복 없이 나오고, 각 열에 1부터 9까지의 숫자가 중복 없이 나오고, 각 3×3짜리 사각형(9개이며, 위에서 색깔로 표시되었다)에 1부터 9까지의 숫자가 중복 없이 나오기 때문이다.
하다 만 스도쿠 퍼즐이 주어졌을 때, 마저 끝내는 프로그램을 작성하시오.
2239번: 스도쿠
스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다
www.acmicpc.net
문제조건
답이 여러 개 있다면 그 중 사전식으로 앞서는 것을 출력한다.
풀이
스도쿠를 풀면 되는 문제이다. 가로, 세로, 정사각형을 확인하며 가능한 숫자를 넣어본다. 단, 그때그때 각 조건을 확인하다보면 시간 초과가 일어남으로 이미 사용하고 있는 숫자들을 체크해 놓는 방식으로 진행해야 한다.
브르트포스 방식으로 풀어주었다. 0번째 row부터 돌며 비어있는(값이 '0'인) 곳을 만나면 1부터 9까지의 숫자를 넣으며 값을 확인해본다. 그 숫자가 가능하다면 값을 넣고, 다음 col의 값을 확인해본다. col은 8까지만 가능함으로 값이 8이라면 다음 row를 확인한다.
사실 답이 여러 개 있다면 사전식으로 앞서는 것을 출력한다는 조건을 읽지 않고 풀었는데 맞았다. 아마 1부터 돌며 그 숫자가 가능한지 확인했기 때문에 사전식으로 가장 앞서는 것을 출력하는 것 같다. 입력이 당연히 띄어쓰기가 있을 줄 알고 int형으로 풀었는데 알고보니 한 줄로 쭉 입력되는 거라 char형으로 받아서 int형으로 바꿔 주었다. 출력할 때 exit쓰는게 뭔가 맘에 안들지만 다른 방법이 생각이 안난다...
코드
#include <iostream> #include <algorithm> #include <vector> using namespace std; char board[9][9]; bool check_row[9][10]; bool check_col[9][10]; bool check_square[9][10]; void sudoku(int r, int c) { if (r == 9) { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { cout << board[i][j]; }cout << "\n"; } exit(0); } if (board[r][c] != '0') c == 8 ? sudoku(r + 1, 0) : sudoku(r, c + 1); if (board[r][c] == '0') { for (int i = 1; i <= 9; i++) { if (!check_row[r][i] && !check_col[c][i] && !check_square[(r / 3) * 3 + c / 3][i]) { check_row[r][i] = true; check_col[c][i] = true; check_square[(r / 3) * 3 + c / 3][i] = true; board[r][c] = i + '0'; c == 8 ? sudoku(r+1, 0) : sudoku(r, c + 1); board[r][c] = '0'; check_row[r][i] = false; check_col[c][i] = false; check_square[(r / 3) * 3 + c / 3][i] = false; } } } } int main() { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { char n; cin >> n; board[i][j] = n; if (n != '0') { check_row[i][n - '0'] = true; //i번째 row에 숫자 n이 있음 check_col[j][n - '0'] = true; //j번째 col에 숫자 n이 있음 check_square[(i / 3)*3 + j / 3][n - '0'] = true; // (i / 3)*3 + j / 3 번째 사각형에 n이 있음 } } } sudoku(0, 0); }
'알고리즘 > BOJ' 카테고리의 다른 글
[백준] 18405번: 경쟁적 전염 (c++) (0) | 2021.10.28 |
---|---|
[백준] 9328번: 열쇠 (c++) (0) | 2021.10.19 |
[백준] 14003번: 가장 긴 증가하는 부분 수열 5 (c++) (0) | 2021.10.07 |
[백준] 12738번: 가장 긴 증가하는 부분 수열 3 (c++) (0) | 2021.10.07 |
[백준] 2623번: 음악프로그램 (c++) (0) | 2021.10.06 |