2 분 소요

1974.스도쿠 검증

문제

스도쿠는 숫자퍼즐로, 가로 9칸 세로 9칸으로 이루어져 있는 표에 1 부터 9까지의 숫자를 채워넣는 퍼즐입니다.

같은 줄에 1에서 9까지 한번만 넣어야하고 3x3크기들도 1에서 9까지의 숫자가 겹치면 안됩니다.

수도쿠가 맞으면 1 아니면 0을 출력하세요.

제약 사항

스도쿠 퍼즐은 채워진 상태로 주어집니다.

생각해보기

우선 9 x 9의 이차원 배열을 받고, 가로로 한 번 세로로 한번 같은 수가 있는지 검증합니다. 빈 값을 하나 만들고 거기에 검증한 수를 더합니다. 그리고 다음에 수가 더해진 값과 다르다면 대체합니다. 같다면 0을 출력합니다.

여기까지 통과했다면 다음은 3x3을 기준으로 검사합니다.

9x9퍼즐 0~2까지 검사, 0~9까지를 3개씩 출력하는 for문을 만들고, for i in range(0, 9,3): 하고 그 밑에 for j in range(i,i+3):

을 만들어서 하면

(0, 0)(0, 1)(0, 2)(0, 3)(0, 4)(0, 5) (1, 0)(1, 1)(1, 2)(1, 3)(1, 4)(1, 5) (2, 0)(2, 1)(2, 2)(2, 3)(2, 4)(2, 5)…

뭔가 복잡해집니다. i,i+3으로 배열을 만들면 대각선으로 가운데 3x3들만 구해집니다.

그래서 저번에 파리잡기 처럼 검사 시작할 곳을 골라서 시작하는 방법을 생각했습니다. 우선 전체 리스트에서 검사할 줄은 0, 3, 6 각 줄에서 검사할 번호는 (0, 3, 6)입니다.

for i in range(0,9,3):

​ for k in range(0, 9, 3)

​ for j in range(k, k+3):

​ sdoku[i][j]

이렇게 검사를 해야겠습니다. 그러면 식을 만들어 보겠습니다.


풀어보기

T = int(input())
for tc in range(1, T+1):
    sdoku = [list(map(int, input().split())) for _ in range(9)]
    anwser = 0
    for i in range(9):
        count = []
        count2 = []
        for j in range(9):
            if sdoku[i][j] not in count and sdoku[j][i] not in count2:
                count.append(sdoku[i][j])
                count2.append(sdoku[j][i])
            else:
                count.append(str(sdoku[i][j]))
                count2.append(str(sdoku[j][i]))
                anwser += 1 
                
    check = [0, 3, 6]
    anwser2 = 0
    for k in check:
        for n in check:
            sol = []
            for l in range(k, k+3):
                for m in range(n, n+3):
                    if sdoku[l][m] not in sol:
                        sol.append(sdoku[l][m])
                    elif sdoku[l][m] in sol:
                        sol.append(str(sdoku[l][m]))
                        anwser2 += 1
    print(f'#{tc} {int(anwser == 0)*int(anwser2 == 0)}')

위에서 고민했던것 처럼 3x3을 검사하는것이 오래 걸렸습니다.
다른 분들이 말하는것을 보니까 1부터 9까지의 합으로 문제를 푸는 것도 있는 것 같습니다.

for k in check:
        for n in check:
            for l in range(k, k+3):
                for m in range(n, n+3):
                    
#이것을 다르게 표현 할 수 있습니다.
for k in range(0,9,3):
    for n in range(0,9,3):
		sam = sdoku[k][n:n+3] + sdoku[k+1][n:n+3] + sdoku[k+2][n:n+3]
        #이렇게하면 3x3의 리스트를 담을 수 있습니다. 이를 다시 for문을 통해 검사해도 됩니다.
        new = []
        answer = 0
        for h in sam:
            if h not in new:
                new.append(h)
            else:
                answer += 1
                

전체 코드에 적용해보면

T = int(input())
for tc in range(1, T+1):
    sdoku = [list(map(int, input().split())) for _ in range(9)]
    anwser = 0
    for i in range(9):
        count = []
        count2 = []
        for j in range(9):
            if sdoku[i][j] not in count and sdoku[j][i] not in count2:
                count.append(sdoku[i][j])
                count2.append(sdoku[j][i])
            else:
                count.append(str(sdoku[i][j]))
                count2.append(str(sdoku[j][i]))
                anwser += 1 
    answer2 = 0
    for k in range(0,9,3):
        for n in range(0,9,3):
            sam = sdoku[k][n:n+3] + sdoku[k+1][n:n+3] + sdoku[k+2][n:n+3]
            new = []
            for h in sam:
                if h not in new:
                    new.append(h)
                else:
                    answer2 += 1
    print(f'#{tc} {int(anwser == 0)*int(answer2 == 0)}')

카테고리:

업데이트:

댓글남기기