-- 예전 기록/BOJ

[ BOJ ] 9291 : 스도쿠 채점 ( SILVER 4 ) / C, Python

rejo 2023. 11. 28. 10:50

문제

스도쿠는 일본어로 "수독(數獨)"을 읽은 것이다. 이는 미국에서 유명한 일본의 한 퍼즐 이름이기도 하다. 스도쿠는 9x9 격자판에 다음 조건을 만족하여 수를 채워 넣는 게임이다.

  • 각 정수 1-9는 각 행에 정확히 한 번씩 등장해야 한다.
  • 각 정수 1-9는 각 열에 정확히 한 번씩 등장해야 한다.
  • 각 정수 1-9는 각 작은 3x3 정사각형에 정확히 한 번씩 등장해야 한다.

남규는 스도쿠에 푹 빠져서 하루종일 스도쿠 문제를 풀던 와중, 스도쿠를 풀었지만 그것이 정답인지를 쉽게 확인할 수 없어 고민에 빠졌다. 불쌍한 남규를 위해 다 채워진 스도쿠 판이 올바른 답인지 판별하는 프로그램을 작성해 주자.

입력

입력의 첫 줄에는 테스트 케이스의 개수가 주어진다.

각 테스트 케이스는 9개의 줄로 이루어져 있으며, 각 줄에는 9개의 정수가 공백으로 구분되어 있다. 각 정수는 1 이상 9 이하이다. 테스트 케이스의 사이에는 빈 줄이 하나 있다.

테스트 케이스의 개수는 100개를 넘지 않는다.

출력

각 테스트 케이스에 걸쳐 "Case x:"를 출력한 후, 공백 한 칸 뒤에 풀이가 올바르면 "CORRECT"를, 아니면 "INCORRECT"를 출력한다. x는 테스트 케이스 번호이며, 1부터 시작한다.

풀이 과정

각 행에 1-9가 한 번씩 들어갔는지, 각 열에 1-9가 한 번씩 들어갔는지, 각 작은 3x3 정사각형에 1-9가 한 번씩 들어갔는지를 모두 체크하여 CORRECT 와 INCORRECT 중 결과를 출력한다. 단순 구현 문제.

C

#include <stdio.h>

int main(void) {
    int t;
    scanf("%d", &t);

    for (int tc = 1; tc <= t; tc++) {
        int arr[9][9] = {0,};
        int done = 1;
        
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) scanf("%d", &arr[i][j]);
        }

        // Garo
        for (int i = 0; i < 9; i++) {
            int now_arr[9] = {0,};
            for (int j = 0; j < 9; j++) now_arr[arr[i][j]-1] = 1;

            for (int j = 0; j < 9; j++) {
                if (now_arr[j] == 0) {
                    done = 0;
                    break;
                }
            }
        }

        // Sero
        for (int j = 0; j < 9; j++) {
            int now_arr[9] = {0,};
            for (int i = 0; i < 9; i++) now_arr[arr[i][j]-1] = 1;

            for (int i = 0; i < 9; i++) {
                if (now_arr[i] == 0) {
                    done = 0;
                    break;
                }
            }
        }

        // Sub-Square
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int now_arr[9] = {0,};
                for (int ni = i * 3; ni < (i + 1) * 3; ni++) {
                    for (int nj = j * 3; nj < (j + 1) * 3; nj++) now_arr[arr[ni][nj]-1] = 1;
                }

                for (int k = 0; k < 9; k++) {
                    if (now_arr[k] == 0) {
                        done = 0;
                        break;
                    }
                }
            }
        }

        if (done) printf("Case %d: CORRECT\n", tc);
        else printf("Case %d: INCORRECT\n", tc);
    }
    return 0;
}

Python

import sys
input = sys.stdin.readline

test = int(input().rstrip())
for t in range(test):
    if t != 0: input().rstrip()
    maps = [list(map(int, input().rstrip().split())) for _ in range(9)]

    done = 0
    #Sero
    for i in range(9):
        S = set()
        for j in range(9):
            S.add(maps[i][j])
        
        if len(S) != 9:
            done = 1
            break

    #Garo
    if done == 0:
        for j in range(9):
            S = set()
            for i in range(9):
                S.add(maps[i][j])

            if len(S) != 9:
                done = 1
                break

        #Block
        if done == 0:
            for bi in range(3):
                for bj in range(3):
                    S = set()
                    for ai in range(3):
                        for aj in range(3):
                            S.add(maps[bi*3+ai][bj*3+aj])
                    
                    if len(S) != 9:
                        done = 1
                        break
                if done == 1: break
    
    if done == 0: print('Case %d: CORRECT'%(t+1))
    else: print('Case %d: INCORRECT'%(t+1))