반응형
728x170
백트래킹에서 그래도 조건이 많이 붙어서 가지치기를 어떻게 하는지 공부할 만한 문제다.
행과 열 처리는 어떻게든 가능하지만
3*3이 어느 칸인지 찾는 것을 조금 고민해볼 필요는 있다.
결국 1~3까지 첫 째 4~6까지 두 번째.. 이렇게 생각하면 어떻게 할 지 감이 온다.
https://www.acmicpc.net/problem/2580
#맞은 풀이
#include<iostream>
#include<vector>
using namespace std;
int pane[9][9]; // 9*9 게임판
bool check = false; // 답을 찾았는지 체크
vector<pair<int, int>> vec; // 채워야 할 곳의 좌표
int number = 0; // 채워야 할 곳의 개수
//조건 1.가로의 합 45, 2.세로의 합 45, 3.3*3 내의 합 45 를 이용해보자.(비효율적..)
// -> 하나의 행에 숫자가 중복되면 안됨, 하나의 열에... 하나의 3*3안에...
// 해당 위치의 값으로 조사
bool numCheck(int a, int b) {
int target = pane[a][b]; // 비교할 숫자
//같은 행에 숫자가 중복되어있나?
for (int i = 0; i < 9; i++) {
//자기 자신을 제외하고 행에서 중복이 된다?
if (target == pane[a][i] && i != b) return false;
//자기 자신을 제외하고 열에서 중복이 된다?
if (target == pane[i][b] && i != a) return false;
}
//자신이 속한 3*3 정사각형 안에서 중복이 된다?
int p = a / 3; // 어느 3*3 인지(행)
int q = b / 3; // 어느 3*3 인지(렬)
for (int i = p * 3; i < p * 3 + 3; i++) {
for (int j = q * 3; j < q * 3 + 3; j++) {
//자신을 제외한 값이 중복이 된다?
if (target == pane[i][j] && i != a && j != b) return false;
}
}
// 모든 조건이 성립하면 true
return true;
}
// 0인 곳에 대해서 모두 선택해야함. 다 선택했을 시에 스도쿠의 조건에 맞나 확인하면 될듯.
void func(int cnt) {
if (check) return; // 이미 결과가 있다면 바로 return
//모두 선택했을 때
if (cnt == number) {
//조건,123을 다거치면 성립
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
cout << pane[i][j] << " ";
}
cout << "\n";
}
//여기까지 왔으면 성립하는 것이 있음.
check = true;
return;
}
//1~9까지 넣어봄
for (int i = 1; i <= 9; i++) {
//선택
auto a = vec[cnt];
int col = a.first;
int row = a.second;
//구현
pane[col][row] = i;
//여기서 숫자를 넣었을 때 checkNum()을 실행해서 넣을 수 있는 숫자인지 확인.
if (numCheck(col, row)) {
//넣을 수 있는 숫자면 넣음.
func(cnt + 1);
}
//복원
pane[col][row] = 0;
}
return;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
//입력받음
for (int x = 0; x < 9; x++) {
for (int y = 0; y < 9; y++) {
cin >> pane[x][y];
if (pane[x][y] == 0) {
vec.push_back({ x,y });
number++;
}
}
}
func(0);
}
728x90
반응형
그리드형
'문제풀이(Problem Solving)' 카테고리의 다른 글
백준, BOJ, 2470번, 두 용액: C++ [CPP] ★★★ (0) | 2022.01.09 |
---|---|
백준, BOJ, 1039번, 교환: C++ [CPP] ★★★ (1) | 2022.01.09 |
백준, BOJ, 15686번, 치킨 배달 : C++ [CPP] ★★★★★ (0) | 2022.01.08 |
백준, BOJ, 5573번, 산책 : C++ [CPP] (0) | 2022.01.07 |
백준, BOJ, 5568번, 카드 놓기 : C++ [CPP] (0) | 2022.01.07 |