APS(Algorithm Problem Solving)

[SWEA] 5644. 무선 충전 (python)

장코 2021. 8. 29. 19:21

문제 바로가기 : [모의 SW 역량 테스트] 무선 충전

 

SW Expert Academy

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

swexpertacademy.com

문제 요약

  • 10*10 영역의 지도에 충전기가 임의로 배치되어있는데, 2명의 사용자가 M 시간 동안 지도를 이동하면서 충전할 수 있는 충전량의 합의 최대값을 구하라
  • 두 사람이 같은 시간에 사용할 수 있는 충전기가 겹치면 충전 되는 양은 반으로 줄어들고, 한 위치에서 두개 이상의 충전기를 사용할 수 있다면 선택해서 사용할 수 있다.

나의 문제 접근 방법

  1. 지도에 충전기를 먼저 나타냈다. 충전을 할 수 있는 모든 곳에 충전할 수 있는 양을 기입했다.
  2. 충전기가 2개 이상이기 때문에 3차원 배열을 이용하여, 모든 충전기가 지도에 입력 될 수 있도록 했다.
  3. 사용자가 이동할 때마다 그 시간에 충전 할 수 있는 최대값을 더해주었다.

내가 푼 코드

def battery(b, a, c, d, e):
    for i in range(c+1):
        # 중심을 기준으로 오른쪽 아래를 채운다.
        for j in range(c-i+1):
            nx = a + j
            ny = b + i
            if 1 <= nx < 11 and 1 <= ny < 11:
                arr[ny][nx][e] = d
        # 중심을 기준으로 왼쪽 위를 채운다.
        for j in range(c-i+1):
            nx = a - j
            ny = b - i
            if 1 <= nx < 11 and 1 <= ny < 11:
                arr[ny][nx][e] = d
        # 중심을 기준으로 오른쪽 위를 채운다.
        for j in range(c-i+1):
            nx = a + j
            ny = b - i
            if 1 <= nx < 11 and 1 <= ny < 11:
                arr[ny][nx][e] = d
        # 중심을 기준으로 왼쪽 아래를 채운다.
        for j in range(c-i+1):
            nx = a - j
            ny = b + i
            if 1 <= nx < 11 and 1 <= ny < 11:
                arr[ny][nx][e] = d




T = int(input())
for tc in range(1, T+1):
    M, A = map(int, input().split())
    route_A = list(map(int, input().split()))  # 사용자 A의 이동 정보
    route_B = list(map(int, input().split()))  # 사용자 B의 이동 정보
    info_AP = [list(map(int, input().split())) for _ in range(A)] # AP의 정보

    # 10*10 2차원 지도에 충전기의 갯수를 추가 해서 3차원 리스트를 만들었다.
    arr = [[[0] * A for _ in range(11)] for _ in range(11)]
	
    # 혹시 몰라서 만들었는데 필요가 없었음
    dx = [-1, 0, 1, 0]
    dy = [0, -1, 0, 1]
	
    
    
    for i in range(len(info_AP)):
        a = info_AP[i][0] # x좌표
        b = info_AP[i][1] # y좌표
        c = info_AP[i][2] # 배터리의 범위
        d = info_AP[i][3] # 충전량
        e = i # 몇번 째 충전기인지 확인
        arr[b][a][i] = d # 충전기 중심부 // 지도의 (b, a)에서 i번째 배터리를 이용해 충전하였고 충전량은 d이다.
        bttery(b, a, c, d, e) # 지도를 모두 채워준다.
	
    
    #### 지도를 시각적으로 보면서 어떤 부분이 잘못되었는지 수시로 확인하였다.
    # for i in range(11):
    #     for j in range(11):
    #         print(arr[i][j], end=" ")
    #     print()
    # print()
	
    
    #### 여기서 부터는 이동 시간에 따라 최대 충전량을 더해준다.
    ans = 0
    ans += max(arr[1][1]) # 사용자 A의 시작점
    ans += max(arr[10][10]) # 사용자 B의 시작점
    user_A = [1, 1]
    user_B = [10, 10]
    dir = {0: [0, 0], 1: [-1, 0], 2: [0, 1], 3: [1, 0], 4: [0, -1]} # 이동 방향
    for i in range(M):
        for j in range(2):
            # 이동 방향에 따른 유저의 위치
            user_A[j] += dir[route_A[i]][j]
            user_B[j] += dir[route_B[i]][j]
        max_A = 0
        max_B = 0
        idx_A = 99
        idx_B = 99
        for j in range(A):
            # A의 최댓값
            if arr[user_A[0]][user_A[1]][j] > max_A:
                max_A = arr[user_A[0]][user_A[1]][j]
                if max_A != 0:
                    idx_A = j
            # B의 최댓값
            if arr[user_B[0]][user_B[1]][j] > max_B:
                max_B = arr[user_B[0]][user_B[1]][j]
                if max_B != 0:
                    idx_B = j
        # 최댓값을 idx가 같으면 같은 충전기를 사용한다는 뜻
        if idx_A != idx_B:
            ans += max_A
            ans += max_B
        else:
            max_A = 0
            max_B = 0
            # 최댓값 제외하고 사용할 수 있는 나머지 충전기의 값이 더 큰 쪽을 사용 
            for j in range(A):
                if j != idx_A and arr[user_A[0]][user_A[1]][j] > max_A:
                    max_A = arr[user_A[0]][user_A[1]][j]
                if j != idx_B and arr[user_B[0]][user_B[1]][j] > max_B:
                    max_B = arr[user_B[0]][user_B[1]][j]
            if max_A >= max_B:
                ans += max_A
                ans += max(arr[user_B[0]][user_B[1]])
            else:
                ans += max(arr[user_A[0]][user_A[1]])
                ans += max_B


    print('#{} {}'.format(tc, ans))

어려웠던 점

쉽게 생각하면 쉬울 수 있는 문제인데, 충전기를 입력시키는데 어렵게 접근을 했다. 처음에 BFS로 입력을 시켰는데 만드는데 까지 너무 오랜시간이 걸렸고, 정확하게 입력이 되지 않았다.

생각을 바꿔 반복문을 통해 더 간단하게 입력을 시킬 수 있었고, 충전기만 지도에 잘 입력되면 시간은 좀 걸리지만 어렵지 않게 답을 구할 수 있었음

물론 문제를 푸는데 여러 방법이 있겠지만 시간이 한정되어있기 때문에 최선의 방법으로 접근하는 연습을 해야한다.