새소식

Computer Science/코딩테스트 문제 풀이

[백준] [파이썬] [그리디] 2170번: 선 긋기

  • -

문제집 추천, 이 문제집에 나온 유형들만 공부해도 코딩테스트는 거뜬: https://www.acmicpc.net/workbook/by/BaaaaaaaaaaarkingDog

 

2170번: 선 긋기 문제보기

문제

매우 큰 도화지에 자를 대고 선을 그으려고 한다. 선을 그을 때에는 자의 한 점에서 다른 한 점까지 긋게 된다. 선을 그을 때에는 이미 선이 있는 위치에 겹쳐서 그릴 수도 있는데, 여러 번 그은 곳과 한 번 그은 곳의 차이를 구별할 수 없다고 하자.

이와 같은 식으로 선을 그었을 때, 그려진 선(들)의 총 길이를 구하는 프로그램을 작성하시오. 선이 여러 번 그려진 곳은 한 번씩만 계산한다.

입력

첫째 줄에 선을 그은 횟수 N (1 ≤ N ≤ 1,000,000)이 주어진다. 다음 N개의 줄에는 선을 그을 때 선택한 두 점의 위치 x, y (-1,000,000,000 ≤ x < y ≤ 1,000,000,000)가 주어진다.

출력

첫째 줄에 그은 선의 총 길이를 출력한다.

예제 입력 1

4
1 3
2 5
3 5
6 7

예제 출력 1

5


처음 문제를 보고 굉장히 간단한 문제라고 생각했다.

먼저 선의 시작 지점을 기준으로 정렬을 한다.

이후 선을 하나씩 보면서 4가지 경우를 생각한다.

위 그림처럼

1. 살펴 볼 현재 선의 왼쪽이 이전 선의 시작점보다 왼쪽에 있고 현재 선의 오른쪽이 이전 선 안에 있을 경우

2. 살펴 볼 현재 선의 왼쪽과 오른쪽이 모두 이전 선 안에 있는 경우

3. 살펴 볼 현재 선의 왼쪽은 이전 선 안에 있고 현재 선의 오른쪽이 범위 밖에 있을 경우

4. 살펴 볼 현재 선이 이전 선 범위에 완전히 벗어난 경우

이다.

선들의 정보를 받을 때 Lines.append(list(map(int, input().split())))를 하였으나 시간초과가 계속 발생하였다.

시간 초과를 벗어나기 위해 선들의 정보를 Lines.append(tuple(map(int, input().split()))) 로 받아야한다.


정답

import sys

sys.stdin=open('input.txt','r')

if __name__=="__main__":
    N=int(input())
    Lines=[]
    for _ in range(N):
        # a,b=map(int,input().split())
        # Lines.append([a,b])
        Lines.append(tuple(map(int, input().split())))

    # Lines.sort(key=lambda x: [x[1],x[0]])
    Lines.sort()
    start=Lines[0][0]
    end=Lines[0][1]
    res=0
    for i in range(1,N):
        l,r=Lines[i]
        if l<start and start<=r<=end:   # 경우 1인경우
            start=l

        elif start<=l<=end and end<r:   # 경우 2인경우
            end=r 

        elif l<=start and r>=end:       # 경우 3인 경우
            start=l
            end=r   

        elif l>end:               # 경우 4인 경우, 즉 새로운 선임 
            res+=(end-start)      # 이전 까지의 선 길이를 저장함 
            start=l               # 새로운 시작과 
            end=r                 # 끝점을 초기화

    res += (end-start)
    print(res)

 


 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.