반응형

문제 출처 :

 

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


알고리즘 분석 :


문제 해결에 필요한 사항

1. x,y 좌표를 정렬 하는 방법

2. 구조체를 이용한 x,y 좌표 묶기


x에 대해 정렬하고 그리고 y에 대해 정렬을 하려고 하면, x값이 같이 따라오지 않는 현상이 발생 할 수 있다.


이를 위해 구조체로 x,y를 묶어두면 조금 더 간단하게 해결할 수 있게된다.


두가지 소스 코드를 볼 때, 


첫번째 코드는 퀵 소트를 구조체에 적용시킨 것,


두번째 코드는 이러한 방식이 그대로 녹아있는 정렬 알고리즘(c++에 내포)을 확인한다.



소스 코드 : 


- 1번 코드 -


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
152
153
154
155
156
157
158
159
160
#include <stdio.h>
 
 
typedef struct xy
{
    int x;
    int y;
}Map;
 
Map map[100001];
 
void SwapX(int a, int b) // a,b 스왑 함수 
{
    Map temp = map[a];
    map[a] = map[b];
    map[b] = temp;
}
 
int PartitionX(int left, int right)
{
    Map pivot = map[left]; // 피벗의 위치는 가장 왼쪽에서 시작
    int low = left + 1;
    int high = right;
 
 
    while (low <= high) // 교차되기 전까지 반복한다 
    {
        while (pivot.x >= map[low].x && low <= right) // 피벗보다 큰 값을 찾는 과정 
        {
            low++// low를 오른쪽으로 이동 
        }
 
        while (pivot.x <= map[high].x && high >= (left + 1)) // 피벗보다 작은 값을 찾는 과정 
        {
            high--// high를 왼쪽으로 이동
        }
 
        if (low <= high)// 교차되지 않은 상태이면 스왑 과정 실행 
        {
            SwapX(low, high); //low와 high를 스왑 
        }
 
    }
    SwapX(left, high); // 피벗과 high가 가리키는 대상을 교환 
    return high;  // 옮겨진 피벗의 위치정보를 반환 
 
}
 
 
void QuickSortX(int left, int right)
{
    if (left <= right)
    {
        int pivot = PartitionX(left, right); // 둘로 나누어서
        QuickSortX(left, pivot - 1); // 왼쪽 영역을 정렬한다.
        QuickSortX(pivot + 1, right); // 오른쪽 영역을 정렬한다.
    }
}
 
 
 
 
 
void SwapY(int a, int b) // a,b 스왑 함수 
{
    Map temp = map[a];
    map[a] = map[b];
    map[b] = temp;
}
 
int PartitionY(int left, int right)
{
    Map pivot = map[left]; // 피벗의 위치는 가장 왼쪽에서 시작
    int low = left + 1;
    int high = right;
 
 
    while (low <= high) // 교차되기 전까지 반복한다 
    {
        while (pivot.y >= map[low].y && low <= right) // 피벗보다 큰 값을 찾는 과정 
        {
            low++// low를 오른쪽으로 이동 
        }
 
        while (pivot.y <= map[high].y && high >= (left + 1)) // 피벗보다 작은 값을 찾는 과정 
        {
            high--// high를 왼쪽으로 이동
        }
 
        if (low <= high)// 교차되지 않은 상태이면 스왑 과정 실행 
        {
            SwapY(low, high); //low와 high를 스왑 
        }
 
    }
    SwapY(left, high); // 피벗과 high가 가리키는 대상을 교환 
    return high;  // 옮겨진 피벗의 위치정보를 반환 
 
}
 
 
void QuickSortY(int left, int right)
{
    if (left <= right)
    {
        int pivot = PartitionY(left, right); // 둘로 나누어서
        QuickSortY(left, pivot - 1); // 왼쪽 영역을 정렬한다.
        QuickSortY(pivot + 1, right); // 오른쪽 영역을 정렬한다.
    }
}
 
 
 
 
 
int main()
{
 
    int n, i;
    int start, end;
    int cnt = 0;
    scanf("%d"&n);
 
    for (i = 0; i < n; i++)
        scanf("%d %d"&map[i].x, &map[i].y);
 
 
    QuickSortX(0, n - 1);
 
    i = 1;
    start = 0;
    end = n - 1;
    while (i < n)
    {
        if (map[i].x == map[i - 1].x)
        {
            cnt = 1;
            start = i - 1;
            while (map[i].x == map[i - 1].x)
            {
                end = i;
                i++;
            }
        }
 
        if (cnt >= 1)
        {
            QuickSortY(start, end);
            start = i;
 
        }
        cnt = 0;
        i++;
    }
    for (i = 0; i < n; i++)
        printf("%d %d\n", map[i].x, map[i].y);
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus




- 2번 코드 -


이 코드는 구조체 x,y를 가진 후 sort라는 알고리즘을 이용하는 방법이다.


sort(시작, 끝+1, 조건);의 방식을 가지고 있는 코드이다.


자세한 내용은 이 게시물 다음 sort알고리즘 설명에서 참조할 수 있다. 


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
#include <cstdio>
#include <algorithm>
 
struct point {
    int x, y;
};
 
point p[100000];
 
bool comp(point const& a, point const& b){
    if(a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}
 
int main() {
    int i, n, x, y;
    scanf("%d"&n);
    for(i=0; i<n; ++i){
        scanf("%d %d "&x, &y);
        p[i] = {x, y};
    }
    std::sort(p, p+n, comp);
    for(i=0; i<n; ++i){
        printf("%d %d\n", p[i].x, p[i].y);
    }
    return 0;
}
Crocus


반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[2846번] 오르막길  (0) 2016.08.30
[1350번] 진짜 공간  (0) 2016.08.30
[7600번] 문자가 몇갤까  (0) 2016.08.14
[10773번] 제로  (0) 2016.08.14
[2004번] 조합 0의 개수  (0) 2016.08.12