본문 바로가기
Problem Solving/SWEA

[SWEA|파이썬] 1873. 상호의 배틀필드 (D3)

by 청량리 물냉면 2023. 5. 19.
반응형
문제

https://tinyurl.com/2zo7gzgf

 

SW Expert Academy

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

swexpertacademy.com

 

 

🐍파이썬
T = int(input())
for test_case in range(1, T + 1):
    h, w = map(int, input().split())
    board = []
    for _ in range(h):
        board.append(list(input()))
    input()
    str_arr = input()
    px, py = 0, 0   #현재 전차의 위치 좌표
    head = ""   #현재 전차의 머리 방향
    for i in range(h):
        for j in range(w):
            if board[i][j] in ["^", "v", "<", ">"]:
                px = j  #현재 전차의 위치 저장
                py = i
                head = board[i][j]  #현재 전차의 머리방향 저장
                board[i][j] = "."   #전차가 존재했던 곳은 .으로 처리(마지막에 전차의 위치만 찾아서 전차 모양으로 바꾸어줄 예정)
                break
    dic = {"U":"^", "D":"v", "L":"<", "R":">"}
    for k in str_arr:
        if k == "U":
            head = dic[k]   #전차의 방향 바꾸기
            # 배열의 범위를 벗어난 경우 건너뜀
            if py-1 >= h or px >= w or py-1 < 0 or px < 0:
                continue
            if board[py-1][px] == ".":  #이동하고자 하는 곳이 평지라면
                py -= 1 #이동하고 좌표값 변경
        elif k == "D":
            head = dic[k]
            if py+1 >= h or px >= w or py+1 < 0 or px < 0:
                continue
            if board[py+1][px] == ".":
                py += 1
        elif k == "L":
            head = dic[k]
            if py >= h or px-1 >= w or py < 0 or px-1 < 0:
                continue
            if board[py][px-1] == ".":
                px -= 1
        elif k == "R":
            head = dic[k]
            if py >= h or px+1 >= w or py < 0 or px+1 < 0:
                continue
            if board[py][px+1] == ".":
                px += 1
        elif k == "S":
            #전차의 방향에 따라 이동할 위치 달라짐
            if head == "^":
                for a in range(py, -1, -1): #현재 y좌표->0까지 탐색
                    if board[a][px] == "#": #포탄 튕겨져나감
                        break
                    if board[a][px] == "*": #포탄으로 벽 뚫음
                        board[a][px] = "."
                        break
            elif head == "v":
                for a in range(py, h): #현재 y좌표->h까지 탐색
                    if board[a][px] == "#":
                        break
                    if board[a][px] == "*":
                        board[a][px] = "."
                        break
            elif head == "<":
                for b in range(px, -1, -1): #현재 x좌표->0까지 탐색
                    if board[py][b] == "#":
                        break
                    if board[py][b] == "*":
                        board[py][b] = "."
                        break
            elif head == ">":
                for b in range(px, w): #현재 x좌표->w까지 탐색
                    if board[py][b] == "#":
                        break
                    if board[py][b] == "*":
                        board[py][b] = "."
                        break
    board[py][px] = head    #최종 py, px 좌표에 head방향으로 전차표시 
    print("#{}".format(test_case), end=" ")
    for i in range(h):
        for j in range(w):
            print(board[i][j], end="")
        print()

 

 

 

다른 풀이 방법

move_list = [(-1, 0), (1, 0), (0, -1), (0, 1)]
 
command_dict = {'U' : 0, 'D' : 1, 'L' : 2, 'R' : 3, 'S' :4,
'^' : 0, 'v' : 1, '<': 2, '>': 3, 0: '^', 1: 'v', 2:'<', 3:'>'}
 
serch_list = ['<', '>', '^', 'v']
 
for t in range(1, int(input()) + 1):
    H, W = map(int, input().split())
    map_list = [list(input()) for _ in range(H)]
    #탱크의 위치를 찾는다.
    for i in range(H):
        for j in range(W):
           if map_list[i][j] in serch_list:
                tank_pos = (i, j, command_dict[map_list[i][j]])
                break
        #브레이크에 안걸렸다면 진행한다.
        else: continue
        #브레이크가 걸렸다면 모든 반복문을 나온다.
        break
    #N값은 안쓰니까 버린다.
    input()
    #명령어 저장
    commands = input()
    #명령어를 순회하면서 처리
    for command in commands:
        temp = command_dict[command]
        #포탄 발싸라면
        if temp == 4:
            #탱크 위치에서 탱크가 바라보는 방향의 위치를 얻는다.
            dy = tank_pos[0] 
            dx = tank_pos[1]
            #포탄은 계속 전진한다.
            while True:
                dy += move_list[tank_pos[2]][0]
                dx +=move_list[tank_pos[2]][1]
                #포탄이 밖으로 벋어나거나 강철벽을 만나면 아무처리도 안한다.
                if 0 > dy or dy >= H or 0 > dx or dx >= W or map_list[dy][dx] == '#':
                    break
                #돌벽을 만나게 된다면
                if map_list[dy][dx] == '*':
                    #평지로 바꿔준다.
                    map_list[dy][dx] = '.'
                    break
        #이동 명령이라면
        else:
            y = tank_pos[0]
            x = tank_pos[1]
            dy = y + move_list[temp][0]
            dx = x + move_list[temp][1]
            map_list[y][x] = command_dict[temp]
            tank_pos = (y, x, temp)
            #맵 범위 안에있고 평지여야함.
            if 0 <= dy < H and 0 <= dx < W and map_list[dy][dx] == '.':
                #기존위치를 평지로 바꾸고
                map_list[y][x] = '.'
                #가야하는 위치에 탱크 표시
                map_list[dy][dx] = command_dict[temp]
                #탱크위치 갱신
                tank_pos = (dy, dx, temp)
    print('#{}'.format(t), end=' ')
    for m in map_list:
        print(''.join(m))

풀이 출처: https://mungto.tistory.com/156

 

상호의 배틀필드 Python(SW Expert Academy)

난이도 : D3 문제번호 : 1873 ※ 저의 풀이가 무조건적인 정답은 아닙니다. 다른 코드가 좀더 효율적이고 좋을 수 있습니다. 다른사람들의 풀이는 언제나 참고만 하시기 바랍니다. 문제 주소 및 출

mungto.tistory.com

 

반응형