[SWEA]12712.파리퇴치3 - 파이썬

    https://swexpertacademy.com/main/code/userProblem/userProblemDetail.do?contestProbId=AXuARWAqDkQDFARa

     

    SW Expert Academy

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

    swexpertacademy.com

    - 델타 접근 연습하려고 푼 문제

    - 처음에 더하기 모양 분사와 곱하기 모양 분사를 나눠서 함수를 만들어줬는데, 합쳐서 할 수 있다는 걸 알게되서

    두번째 풀 때는 8방향 델타를 돌면서 같이 구했다.

    - 주의할 점이 있다면 주어진 세기만큼 반복해서 델타를 돌면서 더해줘야 하는데

    초기화 값을 0이 아닌 해당 좌표에 쓰여진 파리수로 설정해야하고, 1부터 주어진세기-1까지만 반복해줘야한다.

    (0부터 주어진세기-1까지로 설정하면, 세기가 0일때 델타이동을 안한 상태(즉, 해당좌표 그 자체)를 8번 반복하면서 값에 더해지기 때문.

    - 이거 말곤 델타 접근만 잘하면 쉽게 풀 수 있는 문제. 인데 어려웠다.

     

    >> 더하기, 곱하기 모양을 나눠 함수로 만들어서 푼 코드

    T = int(input())
     
    delta_plus = [(-1,0),(0,1),(1,0),(0,-1)]  # +분사 케이스에 사용할 델타
    delta_multi = [(-1,-1),(-1,1),(1,1),(1,-1)]  # *분사 케이스에 사용할 델타
     
    def plus_shape(x,y):
        #좌표가 주어지면, +분사시, area에서 파리개수를 세서 돌려주는 함수
     
        result = area[x][y]
     
        for m in range(1,M):  # 세기를 단계적으로 반복하면서
            for k in range(4):  # 4방향 델타 접근을 해서
                nx = x + delta_plus[k][0]*m
                ny = y + delta_plus[k][1]*m
                if 0<= nx < N and 0 <= ny < N:
                    result += area[nx][ny]  # 결과값에 더해주는 것을 계속한다.
     
        return result
     
    def multiply_shape(x,y):
        #좌표가 주어지면, * 분사시, area에서 파리개수를 세서 돌려주는 함수
     
        result = area[x][y]
     
        for m in range(1,M):
     
            for k in range(4):  # 4방향 델타 접근을 해서
                nx = x + delta_multi[k][0] * m
                ny = y + delta_multi[k][1] * m
                if 0 <= nx < N and 0 <= ny < N:
                    result += area[nx][ny]  # 결과값에 더해주는 것을 계속한다.
     
        return result
     
    for tc in range(1,T+1):
     
        N,M = map(int,input().split())
     
        area = [list(map(int,input().split()))for _ in range(N)] # 파리배열 받아오기
     
        p_max = 0
        m_max = 0
        for i in range(N):
            for j in range(N):  # 모든 좌표에 접근
                # print('d',i,j)
                p_case = plus_shape(i,j)  # +모양으로 퇴치 가능한 파리 수를 pcase에 담기
                m_case = multiply_shape(i,j)  # -모양으로 퇴치 가능한 파리 수를 mcase에 담기
                
                if p_max <= p_case:  # max값 갱신
                    p_max = p_case
                if m_max <= m_case:  # max값 갱신
                    m_max = m_case
     
        ans_max = max(p_max,m_max)  # 둘 중 더 큰값이 최대값
     
        print(f'#{tc}',ans_max)

    >> 수정한 최종 코드

    T = int(input())
     
    for tc in range(1,T+1):
     
        N,M = map(int,input().split())
        grid = [list(map(int,input().split()))for _ in range(N)]
     
        delta = [(-1,-1),(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1)]
     
        ans_lst = []
        for i in range(N):
            for j in range(N):
                plus_shape = grid[i][j]
                multi_shape = grid[i][j]
                for m in range(1,M):  #  세기 M만큼 반복 해서 델타를 돌아야 한다.
     
                    for k in range(8):  # 델타로 새로운 좌표에 접근
                        ni = i + delta[k][0] * m
                        nj = j + delta[k][1] * m
                        if 0<= ni < N and 0<= nj < N:  # 인덱스에서 벗어나지 않으면
                            if k % 2:  # k가 홀수 일때, 즉, 곱하기 변수 델타이면
                                multi_shape += grid[ni][nj]
                            else:  # k가 짝수 일때, 즉 더하기 변수 델타이면
                                plus_shape += grid[ni][nj]
                ans_lst.append(max(multi_shape,plus_shape))  # 해당 좌표에서 +,x 중 맥스값 저장
     
        print(f'#{tc}',max(ans_lst))  # 모든 좌표 맥스값 중 제일 맥스값 출력
        
        '''
    주어진 정사각형 이차원 배열에서 모든 좌표에 접근해야한다.
    특정 한 좌표에 접근 후 해당 좌표에서 플러스모양 분사시 잡는 파리수, 곱하기모양 분사시 잡는 파리수를
    모두 구할 수 있다.
    구한 다음 둘 중 큰 값을 저장해서, 리스트에 담는다.
    모든 좌표에 같은 행동을 반복한다.
    마지막에 맥스값을 출력한다.
     
    델타를 만들 때, 왼쪽부터 시계방향으로 만든다.
    (-1,-1)(-1,0)(-1,1)(0,1)(1,1)(1,0)(1,-1)(0,-1)
    그리고 델타 접근하여 새로운 좌표를 만들 때 인덱스8까지 돌게 할 거고,
    k가 짝수일때는 플러스변수에
    k가 홀수일때는 곱하기변수에 저장하면 된다.
    '''

    댓글