내가 만든 구조체에 대한
"연산자"를 정의하여 사용하는 것이다.
priority_queue에서
a.operator<(b) 가 참일 때
b를 heap의 top에 올려준다
1
2
3
4
5
|
// 최소 힙
bool operator < (const T &a, const T &b)
{
return a.d > b.d;
}
|
cs |
b의 d가 작을 때,
즉 return 값이 true 일 때
b를 heap의 top에 올려준다 -> 최소 힙
<최대 힙>
return a < b;
<최소 힙>
return a > b;
구조체 비교 연산에서는 위와 동일
sort에서는 반대이다.
<Partial sort>
MAX 10만명의 User에 대해 수입이 주어진다.
수입이 가장 큰 user 10명의 uID를 수입에 대해 내림차순으로 구하라.
void addUser (int uID, int income)
user을 추가하는 함수이다.
Parameters:
uID: user id, 0부터 시작해서 순차적으로 증가한다 (0 ≤ uID < 100000)
income: user의 수입, 클수록 우선순위가 높다. 만약 수입이 동일한 경우 uID가 작은 user의 우선순위가 높다.
int getTop10 (int result[MAX_CANDI])
수입이 가장 큰 user 10명의 uID를 수입에 대해 내림차순으로 구하는 함수이다.
총 user의 수가 10명이 되지 않으면 존재하는 user의 uID를 수입에 대해 내림차순으로 구한다.
result의 개수를 반환한다.
Parameters:
result[]: 수입이 큰 순서대로 10개의 uID를 저장한다. (1 ≤ result 개수 ≤ 10)
<소스 코드>
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
|
int genzai;
int user_cnt;
struct info {
int income;
int id;
};
// 수입 최대 힙
// id 최소 힙
bool operator < (const info& a, const info& b)
{
if (a.income == b.income)
{
return a.id > b.id;
}
return a.income < b.income;
}
int arr[100004];
info Heap[100004];
void Heap_push(info data)
{
int idx = ++genzai;
Heap[idx] = data;
while ((idx != 1) && (Heap[idx / 2] < data))
{
info tmp = Heap[idx];
Heap[idx] = Heap[idx / 2];
Heap[idx / 2] = tmp;
idx = idx / 2;
}
}
info Heap_pop()
{
info result = Heap[1];
Heap[1] = Heap[genzai];
genzai--;
// idx
int parent = 1;
int child;
while (true)
{
child = parent * 2;
// 자식노드 두 개 중 우선순위 높은 거 선택
if (child + 1 <= genzai && Heap[child] < Heap[child + 1])
child++;
// 부모가 우선순위 높으면 break
if (child > genzai || Heap[child] < Heap[parent])
break;
info tmp = Heap[child];
Heap[child] = Heap[parent];
Heap[parent] = tmp;
parent = child;
}
return result;
}
void init()
{
user_cnt = 0;
genzai = 0;
}
void addUser(int uID, int height)
{
Heap_push({ height, uID });
user_cnt++;
}
// pop 10번 하고 다시 push 해서 넣어줘야함
int getTop10(int result[10])
{
info tmp[10];
int idx = 0;
while (true)
{
tmp[idx] = Heap_pop();
result[idx] = tmp[idx].id;
idx++;
if (idx == 10 || idx == user_cnt)
break;
}
for (int i = 0; i < idx; i++)
{
Heap_push(tmp[i]);
}
return idx;
}
|
cs |
Heap_pop()에서
genzai == 0이라면 Heap이 비어있는 것이다.
10번 pop 하고 다시 넣는 것은
비효율적이다.
시간 복잡도가 O(10)밖에 안되므로
구조체 배열을 통해 유지할 수도 있다.
別解
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
|
int user_cnt;
struct info {
int income;
int id;
};
// 수입 최대 힙
// id 최소 힙
bool operator < (const info& a, const info& b)
{
if (a.income == b.income)
{
return a.id > b.id;
}
return a.income < b.income;
}
info Top10[11];
int ptr;
void swap(struct info* a, struct info* b)
{
struct info tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void push(int id, int income)
{
int idx = ptr;
Top10[idx] = { income ,id };
idx++;
for (int i = idx - 2; i >= 0; i--)
{
if (Top10[i] < Top10[i + 1])
{
//swap(&Top10[i], &Top10[i + 1]);
info tmp = Top10[i];
Top10[i] = Top10[i + 1];
Top10[i + 1] = tmp;
}
}
if (idx > 10)
idx = 10;
ptr = idx;
}
void init()
{
user_cnt = 0;
ptr = 0;
}
void addUser(int uID, int height)
{
push(uID, height);
user_cnt++;
}
int getTop10(int result[10])
{
for (int i = 0; i < ptr; i++)
result[i] = Top10[i].id;
return ptr;
}
|
cs |
'Heap & 우선순위 큐' 카테고리의 다른 글
친구 추천 SNS (0) | 2024.07.22 |
---|---|
가운데를 말해요 (0) | 2024.02.27 |
Social Media (0) | 2024.02.12 |
카드 정렬하기 (1) | 2024.02.11 |
뉴스 알림 (0) | 2024.02.06 |