기술 블로그

11650번 좌표 정렬하기 본문

알고리즘 문제/BOJ

11650번 좌표 정렬하기

parkit 2018. 9. 18. 23:41
728x90
반응형

※ C언어로 구현



알고리즘 순서


① x, y를 구조체로 생성한다.

② x를 기준으로 먼저 오름차순으로 퀵 정렬을 한다.

③ 같은 x일 경우에만, y를 오름차순 퀵 정렬을 한다.



이 문제에서는 좌표가 중복을 허락하므로, 


31, 37, 74, 80번 째 while문 안에 map과 pivot의 x, y좌표를 비교할 때, '='가 붙는다.


133 ~ 134번 째 주석도 참고하자.



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




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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
 
typedef struct Map
{
    int x;
    int y;
}Map;
 
Map map[100001];
 
int N = 0;
 
void Swap(int a, int b)
{
    Map temp = map[a];
    map[a] = map[b];
    map[b] = temp;
}
 
int partitionX(int start, int end)
{
    Map pivot = map[end]; // pivot 인덱스 = end
    int left = start;
    int right = end;
 
    while (left < right)
    {
        while (map[left].x <= pivot.x && left < right)
        {
            // pivot 보다 큰 값을 찾을 때 까지, 이동
            ++left;
        }
 
        while (map[right].x >= pivot.x && left < right)
        {
            // pivot 보다 작은 값을 찾을 때 까지, 이동
            --right;
        }
 
        if (left < right)
        {
            Swap(left, right);
        }
    }
 
    Swap(right, end);
 
    return right;
}
 
void quickSortX(int start, int end)
{
    int pivot = 0;
 
    if (start < end)
    {
        pivot = partitionX(start, end);
        quickSortX(start, pivot - 1);
        quickSortX(pivot + 1end);
    }
}
 
int partitionY(int start, int end)
{
    Map pivot = map[end]; // pivot 인덱스 = end
    int left = start;
    int right = end;
 
    while (left < right)
    {
        while (map[left].y <= pivot.y && left < right)
        {
            // pivot 보다 큰 값을 찾을 때 까지, 이동
            ++left;
        }
 
        while (map[right].y >= pivot.y && left < right)
        {
            // pivot 보다 작은 값을 찾을 때 까지, 이동
            --right;
        }
 
        if (left < right)
        {
            Swap(left, right);
        }
    }
 
    Swap(right, end);
 
    return right;
}
 
void quickSortY(int start, int end)
{
    int pivot = 0;
 
    if (start < end)
    {
        pivot = partitionY(start, end);
        quickSortY(start, pivot - 1);
        quickSortY(pivot + 1end);
    }
}
 
int main(void)
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++)
    {
        scanf("%d %d"&map[i].x, &map[i].y);
    }
 
    quickSortX(0, N - 1);
 
    int start = 0;
    int end = N - 1;
    int cnt = 0;
 
    for (int i = 0; i < N - 1; i++)
    {
        while (map[i].x == map[i + 1].x)
        {
            end = i + 1;
            ++cnt;
            ++i;
        }
 
        // 위에서 while을 탈출 할 때, i는 어차피 다른 숫자가 나오기 전의 인덱스에 머문다.
        // 즉, 그래서 for문의 i++에 의해서 다시 다른 숫자부터 바로 시작할 수 있다.
        
        if (cnt >= 1)
        {        
            start = end - cnt;
            quickSortY(start, end);
        }
 
        cnt = 0;
    }
 
    for (int i = 0; i < N; i++)
    {
        printf("%d %d\n", map[i].x, map[i].y);
    }
 
    return 0;
}
cs


728x90
반응형

'알고리즘 문제 > BOJ' 카테고리의 다른 글

15489번 파스칼 삼각형  (0) 2018.09.19
4963번 섬의 개수  (0) 2018.09.19
3085번 사탕 게임  (0) 2018.09.18
10828번 스택  (0) 2018.09.17
1963번 소수 경로  (0) 2018.09.16