허비의 기술블로그

[BOJ] 좌표 정렬하기(11650) - PYTHON 본문

BOJ

[BOJ] 좌표 정렬하기(11650) - PYTHON

허비1411 2022. 5. 22. 20:47

(x, y) 좌표의 1차원 배열이 입력으로 들어오면, 이를 오름차순으로 정렬해 출력하는 문제다.

두 좌표의 x값을 비교해 더 작은 좌표가 앞에 오고, 두 좌표의 x값이 같다면 y값을 비교해서 작은 좌표가 앞에 오게 된다.

시간 복잡도: O(NlogN) 

(정렬은 O(N^2)으로 할 수 있지만 N의 최댓값이 100,000이므로 해당 정렬(ex. 버블 / 삽입 / 선택 정렬)을 사용하면 시간 초과가 나게 된다.)

 

11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net


풀이과정

O(NlogN)의 시간 복잡도를 가지는 정렬 방법 중 (ex. 퀵/병합/힙 정렬) 병합 정렬을 사용해서 좌표를 정렬했다.

PYTHON3로 채점했더니 시간 초과가 나서 sys모듈을 import 해서 입력받는 속도를 향상하고, pypy3로 제출했더니 통과했다.


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import sys
 
input = sys.stdin.readline
 
 
def compare(a, b):
    if a[0> b[0]:
        return 1
    elif a[0== b[0]:
        if a[1> b[1]:
            return 1
        else:
            return 0
    else:
        return 0
 
 
def mergeSort(points):
    if len(points) == 1:
        return points
    mid = len(points) // 2
    arr1 = mergeSort(points[0:mid])
    arr2 = mergeSort(points[mid:len(points)])
    index1 = 0
    index2 = 0
    rt = []
    while len(rt) < len(points):
        if index1 >= len(arr1):
            rt.append(arr2[index2])
            index2 += 1
        elif index2 >= len(arr2):
            rt.append(arr1[index1])
            index1 += 1
        else:
            if compare(arr1[index1], arr2[index2]) == 1:
                rt.append(arr2[index2])
                index2 += 1
            else:
                rt.append(arr1[index1])
                index1 += 1
    return rt
 
 
= int(input())
points = []
for _ in range(N):
    points.append(tuple(map(int, input().split())))
points = mergeSort(points)
for x, y in points:
    print(x, y, sep=' ')
 
cs

주석 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import sys
 
input = sys.stdin.readline  # input 입력속도 향상
 
 
def compare(a, b):  # a좌표와 b좌표 비교 (반환값 0: a가 앞으로, 1: b가 앞으로)
    if a[0> b[0]:  # x좌표가 a가 크다면
        return 1  # 1반환
    elif a[0== b[0]:  # x좌표가 같다면
        if a[1> b[1]:  # y좌표 비교해서 a가 크다면
            return 1  # 1반환
        else:
            return 0  # 아닌경우 0 반환
    else:
        return 0  # 아닌경우 0 반환
 
 
def mergeSort(points):  # points배열을 입력받아 정렬
    if len(points) == 1:  # 입력받은 배열의 크기가 1이면
        return points  # 바로 반환
    mid = len(points) // 2  # 가운데 위치
    arr1 = mergeSort(points[0:mid])  # 배열 두개로 나눈후 재귀호출(앞쪽 절반)
    arr2 = mergeSort(points[mid:len(points)])  # 배열 두개로 나눈후 재귀호출(뒷쪽 절반)
    index1 = 0  # arr1의 인덱스
    index2 = 0  # arr2의 인덱스
    rt = []  # 반환값을 저장할 배열
    while len(rt) < len(points):  # rt배열에 값을 다 담을때까지
        if index1 >= len(arr1):  # arr1의 값을 다 담았다면
            rt.append(arr2[index2])  # arr2의 값을 담기
            index2 += 1
        elif index2 >= len(arr2):  # arr2의 값을 다 담았다면
            rt.append(arr1[index1])  # arr1의 값을 담기
            index1 += 1
        else:
            if compare(arr1[index1], arr2[index2]) == 1:  # 비교해서 arr2의 값이 더 작다면(왼쪽에 와야한다면)
                rt.append(arr2[index2])  # arr2 값 담기
                index2 += 1
            else:  # 아닌경우
                rt.append(arr1[index1])  # arr1 값 담기
                index1 += 1
    return rt  # 결과 반환
 
 
= int(input())  # 좌표 갯수
points = []  # 입력 받을 배열
for _ in range(N):
    points.append(tuple(map(int, input().split())))  # 좌표들 입력받기
points = mergeSort(points)  # 정렬
for x, y in points:  # 정렬된 좌표들 출력
    print(x, y, sep=' ')
 
cs

'BOJ' 카테고리의 다른 글

[BOJ] 회의실 배정(1931) - PYTHON  (0) 2022.05.29
[BOJ] N-Queen(9663) - PYTHON  (0) 2022.05.26
[BOJ] 다리놓기(1010) - PYTHON  (0) 2022.05.25
[BOJ] 터렛(1002) - PYTHON  (0) 2022.05.24
[BOJ] 나는야 포켓몬 마스터 이다솜(1620) - PYTHON  (0) 2022.05.23
Comments