ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 1940번 주몽
    Algorithm Study/Python 2024. 3. 22. 19:12

     

    https://www.acmicpc.net/problem/1940

     

    1940번: 주몽

    첫째 줄에는 재료의 개수 N(1 ≤ N ≤ 15,000)이 주어진다. 그리고 두 번째 줄에는 갑옷을 만드는데 필요한 수 M(1 ≤ M ≤ 10,000,000) 주어진다. 그리고 마지막으로 셋째 줄에는 N개의 재료들이 가진 고

    www.acmicpc.net

    풀이

    2개의 숫자를 더해 특정 숫자 M이 나오는지 확인하는 문제이다. N은 최대 15000이고
    모든 경우의 수를 구하게 되면 15000 * 15000 / 2 정도가 나오기 때문에 시간 초과가 발생하게된다.

    즉 더욱 단순하게 풀 수 있어야 하는데 이런 경우에는 투 포인터를 이용하여 양쪽에서 검사하면 쉽게 풀 수 있다.
    입력 받은 숫자를 정렬한 뒤 양쪽에서 확인하면 현재 숫자가 M보다 큰지 작은지 판단하기 쉽다.

    오름차순으로 정렬했다고 가정했을 때 
    1, ....., N 으로 정렬된 숫자에서
    1번째 + N번째 숫자가 M보다 크다면 N을 가리키고 있는 포인터를 한칸 앞으로 당기면 N - 1 번째 숫자는 항상 N보다 작기 때문에 합의 크기를 줄일 수 있다.
    반대로 1번째 + N번째 숫자가 M보다 작다면 1을 가리키고 있는 포인터를 한칸 뒤로 밀면 2번째 숫자는 항상 1번째 숫자보다 크기 때문에 합의 크기를 키울 수 있다.

    이 방법을 이용하여 구하면 총 탐색 횟수는 숫자의 길이 N만큼이 된다.

     

    data = list(map(int, input().split()))
    
    data.sort(reverse=True)
    start = 0
    end = N-1 #len(data)

    먼저 입력받은 데이터를 정렬하고 투 포인터의 시작, 끝 지점을 지정한다.

     

    while True:
        if end <= start:
            break
    
        if data[start] + data[end] == M:
            answer += 1
            start += 1
            end -= 1
        elif data[start] + data[end] > M:
            start += 1
        elif data[start] + data[end] < M:
            end -= 1
    
    print(answer)

    종료 조건은 뒤쪽 포인터와 앞쪽 포인터가 동일한 곳을 선택하거나, 교차되는 순간이다.(모든 숫자 탐색 완료)

    앞에 언급한대로 M을 만족하는 경우는 양쪽 포인터 이동
    M보다 작은 경우는 앞쪽 포인터 이동
    M보다 큰 경우는 뒤쪽 포인터를 이동하는 것으로 탐색을 수행했다.

     

     

    전체 코드

    N = int(input())
    M = int(input())
    
    data = list(map(int, input().split()))
    
    data.sort(reverse=True)
    start = 0
    end = N-1 #len(data)
    answer = 0
    
    while True:
        if end <= start:
            break
    
        if data[start] + data[end] == M:
            answer += 1
            start += 1
            end -= 1
        elif data[start] + data[end] > M:
            start += 1
        elif data[start] + data[end] < M:
            end -= 1
    
    print(answer)

    투 포인터를 활용하면 구현 방법도 시간도 줄일 수 있는 문제이다.
    자주 투포인터 문제를 풀어보는 것으로 문제를 만났을 때 생각을 하는 것이 중요할 것 같다.

     

    'Algorithm Study > Python' 카테고리의 다른 글

    [백준] 1009번 설탕 배달  (0) 2024.07.11
    [백준] 2839번 설탕 배달  (0) 2024.07.01
    [백준] 31416번 가상 검증 기술  (0) 2024.03.22
    [백준] 9655번 돌 게임  (0) 2024.03.17
    [백준] 사과 담기 게임  (0) 2024.03.12

    댓글

From BlackHair