본문으로 바로가기
Archive for AI Study
Algorithm

[Programmers/Python] Level 3: 파괴되지 않은 건물

문제: 파괴되지 않은 건물

문제: 파괴되지 않은 건물

image image image image image image

풀이

def solution(board, skill):
    answer = 0
    board_update = [[0]*(len(board[0])+1) for _ in range(len(board)+1)]
    for tp,r1,c1,r2,c2,degree in skill:
        if tp == 1:
            board_update[r1][c1] -= degree
            board_update[r1][c2+1] += degree
            board_update[r2+1][c1] += degree
            board_update[r2+1][c2+1] -= degree
        else:
            board_update[r1][c1] += degree
            board_update[r1][c2+1] -= degree
            board_update[r2+1][c1] -= degree
            board_update[r2+1][c2+1] += degree
            
     #열방향 전파
    for r in range(len(board)):
        for c in range(1,len(board[0])):
                       board_update[r][c] += board_update[r][c-1]
     #행방향 전파              
    for c in range(len(board[0])):
        for r in range(1,len(board)):
                       board_update[r][c] += board_update[r-1][c]
     #board 업데이트해주기              
    for i in range(len(board)):
        for k in range(len(board[0])):
            board[i][k] += board_update[i][k]
    # print(board)
    #board에서 0보다 큰 개수 count
    for i in range(len(board)):
        for k in range(len(board[0])):
            if board[i][k]>0:
                answer+=1
    return answer      
    '''
    board: 건물 내구도 2차원 정수배열
    skill: 공격 혹은 회복 스킬 - 2차원 정수배열
    [type, r1,c1,r2,c2,degree]
    
    파괴되지 않은 건물의 개수 return
    
    1. skill 하나씩 받아오기
    2. type = 1일떄
        공격 -> (r1,c1)부터 (r2,c2)까지 degree만큼 모두 빼기
        type = 2일때
        회복 -> (r1,c1)부터 (r2,c2)까지 degree만큼 모두 추가시켜주기
    3. board에서 0보다 큰 원소 개수 return
    '''
    '''
    for sk in skill:
        if sk[0] == 1: #공격일때
            for i in range(sk[1],sk[3]+1):
                for k in range(sk[2],sk[4]+1):
                    board[i][k] -= sk[5]
        else: # 회복일때
            for i in range(sk[1],sk[3]+1):
                for k in range(sk[2],sk[4]+1):
                    board[i][k] += sk[5]
    
    for i in range(len(board)):
        for k in range(len(board[0])):
            if board[i][k]>0:
                answer+=1
    print(board)
    return answer
'''
'''
1. board_update에 네개의 꼭짓점 변화량 기록
2. 나중에 board_update 가로세로 전파 한번에 해버리기
3. board_update + board 해서 건물 내구도 O(m*n)으로 구하기
4. board중 0보다 큰 개수 구해서 출력
'''
               

배울점

  1. 그대로 구현하면 \(O(k*m*n)\)이라 시간초과 → 부분합을 쓴 다음에 한번에 Board를 업데이트하면 \(O(K+M*N)\)이라 효율적
  2. 부분합 이용하는것까지는 생각해봤는데, 열, 행순으로 전파를 해서 한번에 업데이트 하는방법은 생각하지 못했음
PythonProgrammers부분 합

Continue exploring

더 읽어보기

모든 글