728x90
반응형
https://www.acmicpc.net/problem/2580
2580번: 스도쿠
스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루
www.acmicpc.net
1. Logic
대표적인 백트래킹 문제.
문제를 푸는 로직은 아래와 같다.
1. 입력을 받으면서 0의 갯수(채워야 하는 빈칸의 갯수)를 같이 카운트한다.
2. solve함수의 파라미터로 0을 넣고 스도쿠 칸이 총 81칸이기 때문에 나누기, 나머지 연산자로 y, x칸의 좌표를 구한다. 나눗셈 연산 : y, 나머지 연산 x
3. 가로, 세로, 3*3에 이미 나온 숫자들이 있는지 확인하고 1~9까지 돌면서 안나온 숫자들중에서 가능한 숫자를 확인한다.
4. 숫자를 맞춰나가면서 처음에 센 0의 갯수와 채워 넣은 숫자의 갯수가 같아지면 바로 출력하고 리턴한다.
2. Code
#include <bits/stdc++.h>
using namespace std;
int sudoku[10][10];
bool numberVis[10];
int zero, solveCnt;
void init(int y, int x) {
int startX = x - x%3;
int startY = y - y%3;
for(int i = 0; i < 10; i++) numberVis[i] = false;
for(int i = 0; i < 9; i++) {
numberVis[sudoku[i][x]] = true;
numberVis[sudoku[y][i]] = true;
}
for(int i = startY; i < startY + 3; i++) {
for(int j = startX; j < startX + 3; j++) {
numberVis[sudoku[i][j]] = true;
}
}
}
bool availableNumCheck(int y, int x, int k) {
int startX = x - x%3;
int startY = y - y%3;
//세로 확인
for(int i = 0; i < 9; i++) {
if(sudoku[i][x] == k) return false;
}
//가로확인
for(int i = 0; i < 9; i++) {
if(sudoku[y][i] == k) return false;
}
//3*3 확인
for(int i = startY; i < startY + 3; i++) {
for(int j = startX; j < startX + 3; j++) {
if(sudoku[i][j] == k) return false;
}
}
return true;
}
bool solve(int n) {
if(solveCnt == zero) {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
cout << sudoku[i][j] << ' ';
}
cout << "\n";
}
return true;
}
int i = n / 9;
int j = n % 9;
if(sudoku[i][j] == 0) {
for(int k = 1; k <= 9; k++) {
init(i, j);
if(!numberVis[k] && availableNumCheck(i, j, k)) {
sudoku[i][j] = k;
numberVis[k] = true;
solveCnt++;
if(solve(n+1)) return true;
sudoku[i][j] = 0;
numberVis[k] = false;
solveCnt--;
}
}
}
else return solve(n+1);
return false;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
cin >> sudoku[i][j];
if(sudoku[i][j] == 0) zero++;
}
}
solve(0);
}
3. Feedback
아래 벨로그의 링크를 참고해서 풀었다. 숫자를 나눠서 나머지와 몫으로 구분한 아이디어가 너무 좋았다. 이분 블로그에 OS도 설명이 잘 되어있어 또한 참고할 것이다!! 정보+1.
BOJ - 2580 스도쿠 해결 전략 (C++)
문제 링크 : 백준 2580번 - 스도쿠 본 문제는 기초적인 Backtracking(Backtracing) 문제이다. DFS적인 흐름의 탐색 함수를 구성해, 정답이 발견되는 경우, 그 순간 함수의 동작을 멈추고 정답을 출력하면
velog.io
알고리즘 Solve 후 제가 생각한 Logic을 기록하는 개인 공부 블로그입니다.
내용 중 최적화가 가능한 부분등은 언제든지 댓글로 틀린 부분 및 피드백 주시면 공부 및 반영하겠습니다🧐
728x90
반응형
'Algorithm > Beakjoon' 카테고리의 다른 글
[백준/Baekjoon] 17144 미세먼지 안녕! C++ :: Implementation (1) | 2023.12.27 |
---|---|
[백준/Baekjoon] 11054 가장 긴 바이토닉 부분 수열 C++ :: Dynamic Programming (0) | 2023.12.25 |
[백준/Baekjoon] 20056 마법사 상어와 파이어볼 C++ :: Implementation (1) | 2023.12.23 |
[백준/Baekjoon] 3055 탈출 C++ :: BFS (1) | 2023.12.22 |
[백준/Baekjoon] 3190 뱀 C++ :: Implementation (1) | 2023.12.21 |