1. 문제

https://www.acmicpc.net/problem/2580

 

2580번: 스도쿠

스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루

www.acmicpc.net

2. 문제의 요구

빈칸을 채워 스도쿠를 완성하라!

 

3. 적용할 알고리즘

백트래킹이 가능하다.

처음에는 빈칸이 10개인 경우 9의 10승으로 시간초과가 날 거라 예상했지만

빈칸을 채울 때마다 조건 확인을 해주면 그 다음 재귀로 넘어가는 경우의 수는 많이 줄어든다.

 

4. 설명

빈칸에 1~9까지 수를 대입해보고

스도쿠 조건에 만족하지 않는다면 그 경우는 패스하고,

만족한다면 다음 빈칸으로 넘어간다.

만약 만족하는 수가 없다면 이전 선택이 잘못된 것이므로

이전의 빈칸으로 돌아간다.

빈칸이 모두 채워졌다면 종료한다.

 

5. 코드

#include<iostream>
#include<vector>
#include<string>
#include<stack>
#include<queue>
#include<tuple>

using namespace std;

const int INF = 0x7f7f7f7f;

typedef long long ll;

int dx[4] = { 1, -1, 0, 0 };
int dy[4] = { 0, 0, 1, -1 };

int board[10][10];

vector<pair<int,int>> zero;

bool Check(int x, int y, int num)
{
	for (int i = 0; i < 9; i++)
	{
		if (board[i][y] == num) return false;
		if (board[x][i] == num) return false;
	}

//주변 9개 칸 중 같은 것이 있는지 확인
//*주의* C언어에서 x / 3 * 3 != x 이다. 
// '/'연산은 나머지를 날려버리기 때문이다.
	for (int i = x / 3 * 3; i < x / 3 * 3 + 3; i++)
	{
		for (int j = y / 3 * 3; j < y / 3 * 3 + 3; j++)
		{
			if (board[i][j] == num) return false;
		}
	}

	return true;
}

int ans[10][10];

void solve(int cur)
{
//빈 칸을 다 채웠을 시 종료
	if (cur == zero.size())
	{
		for (int i = 0; i < 9; i++)
			for (int j = 0; j < 9; j++) ans[i][j] = board[i][j];
		return;
	}

	int cx, cy;
	tie(cx, cy) = zero[cur];

//적절한 수인지 확인 후 다음 빈칸으로 넘어간다
	for (int i = 1; i <= 9; i++)
	{
		if (Check(cx, cy, i))
		{
			board[cx][cy] = i;
			solve(cur + 1);
			board[cx][cy] = 0;
		}
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

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

	solve(0);

	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 9; j++) cout << ans[i][j] << ' ';
		cout << '\n';
	}
}

6. 느낀 점

그냥 대충 순열, 조합 등으로 계산하고 백트래킹 불가로 생각하지 말고

어떠한 조치를 취하면 백트래킹의 시간복잡도가 대폭 줄어들어

완전탐색이 가능하다는 걸 기억하자

'알고리즘&자료구조 실전문제풀이 > 백트래킹' 카테고리의 다른 글

Boj 1799 비숍  (0) 2023.04.18
boj 16987 계란으로 계란치기  (0) 2023.04.14

+ Recent posts