SSONG Cloud

[백준] 2580 스도쿠 본문

Algorithm/백준

[백준] 2580 스도쿠

SSONGMI 2021. 4. 6. 23:18
반응형

문제 출처: www.acmicpc.net/problem/2580

 

2580번: 스도쿠

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

www.acmicpc.net

: 스도쿠의 답을 출력하는게 문제이다.

: 스도쿠의 답이 되기 위해서는 행과 열에 중복된 숫자가 없어야 하고 0행0열부터 시작했을 때 3x3행렬안에도 중복된 값이 있어서는 안된다.

: 따라서 각각의 경우마다 중복체크를 할 수 있는 함수를 별도로 만들어준다.

: 비어있던 칸들을 미리 리스트로 만든 후 그 리스트를 재귀적으로 접근하여 위의 3가지 경우 모두 중복되지 않으면 해당 숫자를 집어넣고 다음 비어있는 칸으로 이동할 수 있도록 한다.

: 만약 비어있던 칸들을 모두 채우는 경우가 바로 답이 되기 때문에 이 경우에 답을 출력하고 시스템을 종료한다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringBuilder sb = new StringBuilder();
	static StringTokenizer st;
	static int[][] sudoku = new int[9][9];
	static ArrayList<Point> list = new ArrayList<>();
	static class Point{
		int r, c;

		public Point(int r, int c) {
			super();
			this.r = r;
			this.c = c;
		}

		@Override
		public String toString() {
			return "Point [r=" + r + ", c=" + c + "]";
		}
		
	}
	public static void main(String[] args) throws IOException {
		for(int i = 0; i < 9; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0; j < 9; j++) {
				sudoku[i][j] = Integer.parseInt(st.nextToken());
				if(sudoku[i][j] == 0) list.add(new Point(i, j));
			}
		}
		setNumber(0);
	
		
	
	}
	private static void setNumber(int idx) {
		if(idx == list.size()) {
			for(int i = 0; i < 9; i++) {
				for(int j = 0; j < 9; j++) {
					System.out.print(sudoku[i][j] + " ");
				}
				System.out.println();
			}
			System.exit(0);
		}
		int r = list.get(idx).r;
		int c = list.get(idx).c;
//		System.out.println(idx);
		for(int i = 1; i < 10; i++) {
			sudoku[r][c] = i;
			// 가로줄 확인			
			// 세로줄 확인
			// 정사각형 확인
			if(checkRow(r) && checkCol(c) && checkBox(r, c)) {
				setNumber(idx+1);
			}
		}
		sudoku[r][c] = 0;
		
	}
	static int[] dr = {0, 1, 2};
	private static boolean checkBox(int r, int c) {
		int sr = r/3;
		int sc = c/3;
		sr *= 3;
		sc *= 3;
		boolean[] v = new boolean[10];
		for(int i = 0; i < 3; i++) {
			int nr = sr+dr[i];
			for(int j = 0; j < 3; j++) {
				int nc = sc + dr[j];
				if(sudoku[nr][nc] != 0 && v[sudoku[nr][nc]]) return false;
				v[sudoku[nr][nc]] = true;
				
			}
		}
		return true;
	}
	private static boolean checkCol(int c) {
		boolean[] v = new boolean[10];
		for(int r = 0; r < 9; r++) {
			if(sudoku[r][c] != 0 && v[sudoku[r][c]]) return false;
			v[sudoku[r][c]] = true;
		}
		return true;
	}
	// 가로줄 확인
	private static boolean checkRow(int r) {
		boolean[] v = new boolean[10];
		for(int c = 0; c < 9; c++) {
			if(sudoku[r][c] != 0 && v[sudoku[r][c]]) return false;
			v[sudoku[r][c]] = true;
		}
		return true;
	}
}	
반응형

'Algorithm > 백준' 카테고리의 다른 글

[백준] 6593 상범 빌딩  (0) 2021.04.07
[백준] 1904 01타일  (0) 2021.04.06
[백준] 1043 거짓말  (0) 2021.04.05
[백준] 1929 소수 구하기  (0) 2021.04.01
[백준] 11054 가장 긴 바이토닉 부분 수열  (0) 2021.04.01
Comments