[코드트리] 싸움땅

AFL·2024년 10월 16일

삼성 SW 역량 테스트 기출 문제

싸움땅

# 정답 코드 

n, m, k = map(int, input().split())

board = [ [ [0] for _ in range(n+1) ] for _ in range(n+1) ]
pboard = [ [ [] for _ in range(n+1) ] for _ in range(n+1) ]
player = [ [] for _ in range(m+1) ]
score = [ 0 for _ in range(m) ]
for i in range(1, n+1):
    inl = list(map(int, input().split()))
    for l in range(len(inl)):
        board[i][l+1] = [ inl[l] ]
for i in range(1, m+1):
    inl = list(map(int, input().split()))
    player[i] = inl+[0]

for i in range(1, m+1):
        pboard[player[i][0]][player[i][1]] = [ i ]

def fisrt_move(mover, x, y, d, inlose=False):
    nx, ny = x, y
    
    # 한칸 이동
    if d == 0: # 북
        nx = x - 1
        # ny = y
    if d == 1: # 동
        # nx = x
        ny = y + 1
    if d == 2: # 남
        nx = x + 1
        # ny = y
    if d == 3: # 서
        # nx = x
        ny = y - 1

    # 만약 이동한 칸이 범위를 벗어나면, 
    ## 방향 반대로 바꾸기
    if nx > n: # and 1 <= ny <= n:
        d = 0 # 3 # 0
    elif ny > n: # and 1 <= nx <= n:
        d = 3 # 0 # 3  
    elif nx < 1: # and 1 <= ny <= n:
        d = 2 # 1 # 2 
    elif ny < 1: # and 1 <= nx <= n:
        d = 1 # 2 # 1 
    else:
        return nx, ny
    # 그리고 한칸 이동
    if d == 0: # 북
        nx = x - 1
        ny = y
    if d == 1: # 동
        nx = x
        ny = y + 1
    if d == 2: # 남
        nx = x + 1
        ny = y
    if d == 3: # 서
        nx = x
        ny = y - 1
    player[mover][2] = d
    return nx, ny

def move(mover, x, y, d, inlose=False):
    nx, ny = x, y

    if d == 0: # 북
        nx = x - 1
        ny = y
    if d == 1: # 동
        nx = x
        ny = y + 1
    if d == 2: # 남
        nx = x + 1
        ny = y
    if d == 3: # 서
        nx = x
        ny = y - 1

    return nx, ny

def peace(mover, mx, my):
    cur = player[mover][4]  # 현재 총의 공격력
    max = 0
    gun_list = board[mx][my]  # 좌표의 총 리스트
    rest = []
    
    if len(gun_list) != 0: # if gun_list[0] != 0:  # 총이 하나라도 있으면
        
        
        gun_list.append(cur)  # 있던총, 내려놓은 총들 
        gun_list.sort(reverse=True) # 내림차순해서 가장 큰걸 앞으로
        
        player[mover][4] = gun_list[0]  # 젤 큰거 가지기 
        board[mx][my] = gun_list[1:]  # 나머지는 두기

def lose(loser, x, y):
    inlose = True
    if player[loser][4] != 0:  # 수중에 있던 총 내려놓기
        if board[x][y] == [0]:
            board[x][y] = [ player[loser][4] ]
        else:
            board[x][y].append(player[loser][4])
        player[loser][4] = 0
        
    while True:
        nx, ny = move(loser, player[loser][0], player[loser][1], player[loser][2], inlose)

        # 격자 밖이거나 다른 사람 있으면 빈칸 보일때까지 90도 돌리기 
        if nx<1 or nx>n or ny<1 or ny>n or len(pboard[nx][ny]) != 0:
            player[loser][2] += 1
            if player[loser][2] > 3:
                player[loser][2] = 0
        else:
            pboard[nx][ny].append(loser)  # 새로 좌표 바꾸기
            pboard[x][y].remove( loser )  # pboard[x][y] = []
            player[loser][0] = nx
            player[loser][1] = ny
            
            ##### ** 여기에서 중요 ** #####   
            ### 그냥 peace를 부르면 안된다. 
            ### 이미 총을 내려둔 상태이기에 총은 0개 들고 있음
            ### 따라서 자신의 것을 또 내려놓을 필요가 없다.
            ### 이동한 좌표에 있는 총 중에 
            
            # peace(loser, nx, ny) # 총 줍기
            # cur = player[loser][4]  # 현재 총의 공격력
            gun_list = board[nx][ny]
            if len(gun_list) != 0:   # if gun_list[0] != 0: 
                # gun_list.append(cur)
                gun_list.sort(reverse=True)
                
                player[loser][4] = gun_list[0]
                board[nx][ny] = gun_list[1:]
            break

def win(winner, x, y):
    # pboard[x][y] = [winner]
    peace(winner, x, y)

def fight(hum1, hum2, x, y):
    
    # sc = 0
    p1 = player[hum1][3]+player[hum1][4]
    p2 = player[hum2][3]+player[hum2][4]
    
    if p1 > p2:
        lose(hum2, x, y)
        pboard[x][y] = [hum1]
        win(hum1, x, y)
        sc = p1 - p2
        score[hum1-1] +=  sc
        
    elif p1 < p2:
        lose(hum1, x, y)
        pboard[x][y] = [hum2]
        win(hum2, x, y)
        sc = p2 - p1
        score[hum2-1] += sc
        
    elif p1==p2:
        if player[hum1][3] > player[hum2][3]:
            lose(hum2, x, y)
            pboard[x][y] = [hum1]
            win(hum1, x, y)
            
            sc = p1 - p2
            score[hum1 - 1] += sc
            
        if player[hum1][3] < player[hum2][3]:
            lose(hum1, x, y)
            pboard[x][y] = [hum2]
            win(hum2, x, y)
            
            sc = p2 - p1
            score[hum2 - 1] += sc
            
for kk in range(k):
    # 1. 모든 사람 이동
    for p in range(1, m+1):
        
        x = player[p][0]
        y = player[p][1]
        # 새 좌표로 이동
        nx, ny = fisrt_move(p, x, y, player[p][2])
        player[p][0] = nx
        player[p][1] = ny
        
        pboard[x][y].remove( p )  # pboard[x][y] = []  
        pboard[nx][ny].append( p )

        # 2. 평화 혹은 싸움
        if len(pboard[nx][ny]) == 1:  # 한명 있으면
            peace(pboard[nx][ny][0], nx, ny)
        else:  # 두명 있으면
            fight(pboard[nx][ny][0], pboard[nx][ny][1], nx, ny)
        
for _ in score:
    print(_, end=' ')

profile
공부해서 남주자

0개의 댓글