STUDY/Algorithm

[SWEA] 5650 핀볼 게임

sinawi95 2022. 3. 16. 12:19
728x90

SW Expert Academy 5650. [모의 SW 역량테스트] 핀볼 게임

 

SW Expert Academy

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

swexpertacademy.com

구현, 시뮬레이션 문제이고 딱 삼성 기출같은 문제였다. 문제 자체는 어렵진 않았고 꽤 복잡했다.

입력을 받고 모든 점마다 시뮬레이션을 돌린뒤 가장 점수가 높은 것을 출력하면 되었는데 시뮬레이션 돌릴때 꽤 애를 먹었다.

시뮬레이션 돌릴땐 블록이 아닌 모든 점에 대해서 진행했는데 최대한 중복되는 점들을 제거 하려고 노력했다. 예를 들면 시작하자마자 벽을 만나는 경우를 제거했고(이 부분은 1점을 줘야했는지 고민하긴했다.), 진행 방향의 다음 점이 빈 곳이면 중복이 되므로 제거했다.

조건이 되는 점들만 시뮬레이션을 돌렸다. 시뮬레이션에선 각 점마다 하나하나 확인하면서 돌렸다. 웜홀은 딕셔너리로 만들었는데 시뮬레이션을 돌릴때 wormhole[(r,c)] 로 이동하는 위치를 파악하기 위해서 사용했다. 방향을 바꾸는건 따로 함수를 빼서 조건문으로 처리했다.

모든 조건들을 if문으로 처리하였으나 미처 빼먹은 케이스들이 있었다. 웜홀에서 나와서 바로 벽을 만나는 경우와 같이 방향이 바뀌거나 혹은 새로운 위치로 변하는 경우 문제가 생겼고 디버깅으로 일일이 찾아가면서 분기 처리 해주었다.

 

 

import sys
sys.stdin = open("swea_5650.txt", "r")

def change_direction(d, block):
    # d: 0, 1, 2, 3 => r, d, l, u
    ret = None
    if block == 1:
        if d == 2:       ret = 3
        elif d == 1:     ret = 0
        else:            ret = (d + 2) % 4
    elif block == 2:
        if d == 2:       ret = 1
        elif d == 3:     ret = 0
        else:            ret = (d + 2) % 4
    elif block == 3:
        if d == 0:       ret = 1
        elif d == 3:     ret = 2
        else:            ret = (d + 2) % 4
    elif block == 4:
        if d == 0:       ret = 3
        elif d == 1:     ret = 2
        else:            ret = (d + 2) % 4
    elif block == 5:
        ret = (d + 2) % 4
    else:
        ret = d
    return ret

def main():
    T = int(input())
    for tc in range(1, T + 1):
        # 0 initiate
        answer = 0
        N = int(input())
        wormhole = dict()
        _map = []

        dr = [0, 1, 0, -1]  # clockwise
        dc = [1, 0, -1, 0]
        for i in range(N):
            _map.append(list(map(int, input().split())))
            for j in range(N):
                if 6 <= _map[i][j] <= 10:
                    if not wormhole.get(_map[i][j]):
                        wormhole[_map[i][j]] = (i, j)
                    else:
                        wormhole[(i, j)] = wormhole[_map[i][j]]
                        wormhole[wormhole[_map[i][j]]] = (i, j)
        # 1 simulate
        for i in range(N):
            for j in range(N):
                if _map[i][j]:
                    # 아무것도 없는 블록만 실행
                    continue
                for d in range(4):
                    r, c = i, j
                    nr = r + dr[d]
                    nc = c + dc[d]
                    if 0 > nr or nr >= N or 0 > nc or nc >= N:
                        # 처음 부터 벗어 나는 방향은 중복 되는 방향임
                        continue
                    if _map[nr][nc] <= 0:
                        # 해당 방향이 비어 있으면 중복 되는 방향
                        # 블랙홀이면 score 0
                        continue

                    # 진행 방향에 블록이 있는 경우 실행
                    score = 0
                    while True:
                        nr = r + dr[d]
                        nc = c + dc[d]
                        if 0 <= nr < N and 0 <= nc < N:
                            if _map[nr][nc] == -1 or (nr == i and nc == j):
                                # blackhole or starting point
                                break
                            if not _map[nr][nc]:
                                # empty space
                                r, c = nr, nc
                                continue

                            if 1 <= _map[nr][nc] <= 5:
                                # reflecting block
                                # if reflecting, score up
                                nd = change_direction(d, _map[nr][nc])
                                if abs(nd - d) == 2 and r == i and c == j:
                                    break
                                score += 1
                                r, c = nr, nc
                                d = nd
                                continue

                            elif 6 <= _map[nr][nc] <= 10:
                                # wormhole
                                r, c = wormhole[(nr, nc)]
                        else:
                            # if outside, change direction
                            if r == i and c == j:
                                break

                            d = (d + 2) % 4
                            score += 1
                            if 0 < _map[r][c] <= 5:
                                d = change_direction(d, _map[r][c])
                                score += 1
                            elif 5 < _map[r][c] <= 10:
                                r, c = wormhole[(r, c)]

                    answer = max(answer, score)

        # 2 output
        print(f"#{tc} {answer}")


if __name__ == "__main__":
    main()