본문 바로가기

알고리즘/문제 풀이

SW Expert Academy 1974. 스도쿠 검증

SW Expert Academy

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

1. 내 코드

import java.util.HashSet;
import java.util.Scanner;


class Solution
{
    public static void main(String args[])
    {
        Scanner sc= new Scanner(System.in);
        int T;
        T=sc.nextInt();
        Test:
        for (int test_case = 1; test_case <= T; test_case++) {
            // 1. 2차원 배열로 값들을 받는다.
            int[][] sudoku = new int[10][10];
            HashSet<Integer> set = new HashSet<>();

            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    sudoku[i][j] = sc.nextInt();
                }
            }
            // --> 2차원 배열을 각 요건에 맞게 Hash set에 넣고 set의 size가 9가 아니면, 0 출력하면 될 듯.
            // 2. 가로에서 겹치는 값이 있는지 검증한다. -> 있으면 바로 0 출력 후 continue
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    set.add(sudoku[i][j]);
                }
                if(set.size() != 9){
                    System.out.printf("#%d %d\n" ,test_case, 0);
                    continue Test;
                }
                set.clear();
            }
            // 3. 세로에서 겹치는 값이 있는지 검증한다. -> 있으면 바로 0 출력 후 continue
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    set.add(sudoku[j][i]);
                }
                if(set.size() != 9){
                    System.out.printf("#%d %d\n" ,test_case, 0);
                    continue Test;
                }
                set.clear();
            }
            // 4. 3x3에서 겹치는 값이 있는지 검증한다. -> 있으면 바로 0 출력 후 continue
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    for (int k = i*3; k <= (i*3)+2; k++) {
                        for (int l = j*3; l <= (j*3)+2; l++) {
                            set.add(sudoku[k][l]);
                        }
                    }
                    if(set.size() != 9){
                        System.out.printf("#%d %d\n" ,test_case, 0);
                        continue Test;
                    }
                    set.clear();
                }

            }
            System.out.printf("#%d %d\n" ,test_case, 1);

        }


    }

}

2. 다른 사람 코드 

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
class Solution {
    public static void main(String args[]) throws Exception {
        //System.setIn(new FileInputStream("src/input.txt"));
 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
 
        int[][] arr = new int[9][9];
 
        for (int test_case = 1; test_case <= T; test_case++) {
            // 배열 입력
            for (int i = 0; i < 9; i++) {
                StringTokenizer st = new StringTokenizer(br.readLine());
                for (int j = 0; j < 9; j++) {
                    arr[i][j] = Integer.parseInt(st.nextToken());
                }
            }
 
            // 1~9까지, 중복되는 숫자가 x > 1출력, 아니면 0출력
            // 총합은 45
            int answer = 0;
            for (int i = 0; i < 9; i++) {
                int hap1 = 0; // 가로 합
                int hap2 = 0; // 세로 합
                int hap3 = 0; // 3x3 부분배열 합
                for (int j = 0; j < 9; j++) {
                    hap1 += arr[i][j];
                    hap2 += arr[j][i];
                    hap3 += arr[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3];
                }
                if (hap1 != 45 || hap2 != 45 || hap3 != 45) {
                    answer = 0;
                    break;
                } else {
                    answer = 1;
                }
            }
 
            System.out.print("#" + test_case + " ");
            System.out.println(answer);
 
        }
 
    }
 
}

3x3 계산 부분이 인상 깊다. 

해당 부분의 로직은 이렇게 돌아간다.

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                // 행의 i 계산 부분은 i가 0,1,2일 때 0 / 3,4,5일 때 3 / 6,7,8일 때 6
                // 행의 j 계산 부분은 j가 0,1,2일 때 0/ 3,4,5일 때 1, / 6,7,8일 때 2

                // 열의 i 계산 부분은 i가 0,3,6일때 0 / 1,4,7일때 3 / 2,5,8일때 6씩 더해줌
                // 열의 j 계산 부분은 j가 0,3,6일때 0 / 1,4,7일때 1 / 2,5,8일때 2씩 더해줌
            
                System.out.printf("[%d][%d] ",((i / 3) * 3 )+ (j / 3),((i % 3) * 3 )+ (j % 3));
            }
            System.out.println();
        }

이런 방법을 생각하다니 대단하다. 

행과 열의 i 부분은 큰 톱니바퀴, j 부분은 작은 톱니바퀴라 볼 수 있다.