[SW Expert Academy] 15155 . 오목판정

sun1·2023년 3월 4일
0

im_test

목록 보기
15/22
post-thumbnail

문제

SWEA 15155 . 오목판정
https://swexpertacademy.com/main/talk/solvingClub/problemView.do?solveclubId=AYYSRkW6cRoDFAVw&contestProbId=AYLI_hUK4yADFASv&probBoxId=AYaPtr1K-_0DFARM+&type=USER&problemBoxTitle=230303%3A+%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4_5&problemBoxCnt=6

  • N X N 크기의 판이 있다. 판의 각 칸에는 돌이 있거나 없을 수 있다. 돌이 가로, 세로, 대각선 중 하나의 방향으로 다섯 개 이상 연속한 부분이 있는지 없는지 판정하라.

풀이

조건

  • 테스트 케이스의 수 T와 N(5 ≤ N ≤ 20)이 주어진다.
  • N x N 배열에서 각 문자는 ‘o’또는 ‘.’으로, ‘o’는 돌이 있는 칸을 의미하고, ‘.’는 돌이 없는 칸을 의미한다.
  • 각 테스트 케이스 마다 돌이 다섯 개 이상 연속한 부분이 있으면 “YES”를, 아니면 “NO”를 출력한다.

풀이 순서

  • T, N, 배열을 입력값으로 받는다.
  • 가로, 세로, 대각선에 돌이 다섯 개 이상 연속한 부분이 있는지 판단할 수 있는 함수를 만들어 있으면 “YES”를, 아니면 “NO”를 출력한다.

코드

Python

cf. 각 코드마다 매력적인 부분들이 다르다 :)

코드 1

  • 배열 상황을 분석하는 법 1 (함수)
def check():
    # 가로
    for a in arr:
        for i in range(N + 1 - 5):
            if a[i:i + 5] == 'o' * 5:  # i ~ i+4 (5개)가 다 돌이 있는지 확인하기
                return 'YES'

    for i in range(N):
        for j in range(N):
            # 세로
            tmp = 0
            for k in range(5):
                if j + k == N:  # 범위 벗어나면 그만두기
                    break
                if arr[j + k][i] == 'o':
                    tmp += 1
                if tmp == 5:
                    return 'YES'
            # 대각선 왼쪽위 오른쪽아래
            tmp = 0
            for k in range(5):
                if i + k == N or j + k == N:  # 어느 한점이 끝에 도달하면 그만둬라
                    break
                if arr[i + k][j + k] == 'o':
                    tmp += 1
                    if tmp == 5:
                        return 'YES'
            # 대각선 오른쪽위 왼쪽아래
            tmp = 0
            for k in range(5):
                if i + k == N or j - k == -1:
                    break
                if arr[i + k][j - k] == 'o':
                    tmp += 1
                    if tmp == 5:
                        return 'YES'
    return 'No'  # 모두 해당상항 없으면 NO를 리턴

T = int(input())
for tc in range(1, T + 1):
    N = int(input())
    arr = [input() for _ in range(N)]

    print(f'#{tc} {check()}')

코드 2

  • 배열 상황을 분석하는 법 1 (함수를 안쓰면 한꺼번에 끝낼 수 있도록 가로, 세로, 대각선을 같은 for문 쓰기 ->테스트 케이스가 여러개라 exit()를 쓸수 없으므로)
T= int(input())
for tc in range(1, T+ 1):
    N = int(input())
    arr = [list(map(str, input())) for _ in range(N)]

    result = "NO"
    for i in range(N):
        for j in range(N):
            if arr[i][j] == 'o':
                # 세로
                cnt = 0
                for k in range(5): #연속 5개
                    if i + k == N: #끝까지 도착하면 그만둬라
                        break
                    else:
                        if arr[i + k][j] == 'o':
                            cnt += 1
                if cnt == 5:
                    result = "YES"
                    break
                # 가로
                cnt = 0
                for k in range(5):
                    if j + k == N:
                        break
                    else:
                        if arr[i][j + k] == 'o':
                            cnt += 1
                if cnt == 5:
                    result = "YES"
                    break
                # 대각 1 (왼->오)
                cnt = 0
                for k in range(5):
                    if i + k == N or j + k == N: #어느 한점이 끝에 도달하면 그만둬라
                        break
                    else:
                        if arr[i + k][j + k] == 'o':
                            cnt += 1
                if cnt == 5:
                    result = "YES"
                    break
                # 대각 2 (오->왼)
                cnt = 0
                for k in range(5):
                    if i + k == N or j - k == -1:
                        break
                    else:
                        if arr[i + k][j - k] == 'o':
                            cnt += 1
                if cnt == 5:
                    result = "YES"
                    break
    print(f'#{tc} {result}')

코드 3

  • 돌이 놓여져 있는 지점에서 이동해서 계속 돌이 놓여져 있는지 확인하는 법
T = int(input())
for tc in range(1, T + 1):
    N = int(input())
    arr = [input() for _ in range(N)]

    dy = [0, 1, 1, 1]
    dx = [1, 0, 1, -1]
    tmp = False
    for i in range(N):
        for j in range(N):
            if arr[i][j] == 'o':
                for k in range(4):
                    y = i
                    x = j
                    cnt = 0
                    while 0 <= y <= N - 1 and 0 <= x <= N - 1 and arr[y][x] == 'o':
                        cnt += 1
                        y += dy[k]
                        x += dx[k]
                    if cnt >= 5:
                        print(f'#{tc} YES')
                        tmp = True

    if tmp == False:
        print(f'#{tc} NO')

코드 4

  • 돌이 놓여져 있는 좌표값들을 다 뽑아서 수들이 연속하는지 확인하는 법
def check(lst_i,lst_j):
    if [i for i in range(5)] in lst_i:
        print(f'#{tc} YES')
        return
    if [i for i in range(5)] in lst_j:
        print(f'#{tc} YES')
        return
    for i in range(20):
        if lst_i[i] == [0]:
            tmp=0
            for k in range(1,5):
                if lst_i[i+k] == [k]:
                    tmp+=1
            if tmp == 4:
                print(f'#{tc} YES')
                return
        if lst_i[i] == [4]:
            tmp=0
            for k in range(1,5):
                if lst_i[i+k] == [4-k]:
                    tmp+=1
            if tmp == 4:
                print(f'#{tc} YES')
                return
        if lst_j[i] == [0]:
            tmp=0
            for k in range(1,5):
                if lst_j[i+k] == [k]:
                    tmp+=1
            if tmp == 4:
                print(f'#{tc} YES')
                return
        if lst_j[i] == [4]:
            tmp=0
            for k in range(1,5):
                if lst_j[i+k] == [4-k]:
                    tmp+=1
            if tmp == 4:
                print(f'#{tc} YES')
                return
    print(f'#{tc} NO')

T=int(input())
for tc in range(1,T+1):
    N=int(input())
    arr=[input() for _ in range(N)]
    lst_i=[[] for _ in range(20)]
    lst_j=[[] for _ in range(20)]
    for i in range(N):
        for j in range(N):
            if arr[i][j] == 'o':
                lst_i[i].append(j)
                lst_j[j].append(i)
    check(lst_i,lst_j)

0개의 댓글