Algorithm/BOJ
KOI 2019 중등부 2차 / 개구리 점프 - 17619
jhg0406
2020. 7. 29. 00:59
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
|
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N, Q;
struct disjointSet {
vector<int> parent, rank;
disjointSet(int n) : parent(n), rank(n, 0) {
for(int i= 0; i<n; ++i) parent[i] = i;
}
int find(int u) {
if(u == parent[u]) return u;
return parent[u] = find(parent[u]);
}
void merge(int u, int v) {
u = find(u);
v = find(v);
if(u == v) return;
if(rank[u] < rank[v]) swap(u, v);
parent[v] = u;
if(rank[u] == rank[v]) rank[u]++;
}
};
struct node {
int s;
int e;
int idx;
};
bool operator<(node& n1, node& n2) {
return n1.s < n2.s;
}
node arr[100000];
int main() {
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> N >> Q;
disjointSet set(N);
int x1, x2, y;
for(int i = 0; i<N; ++i) {
cin >> x1 >> x2 >> y;
arr[i] = {x1, x2, i};
}
sort(arr, arr+N);
int E = arr[0].e;
for(int i = 0; i<N-1; ++i) {
if(E >= arr[i+1].s) {
set.merge(arr[i].idx, arr[i+1].idx);
E = max(E, arr[i+1].e);
} else E = arr[i+1].e;
}
for(int i = 0; i<Q; ++i) {
cin >> x1 >> x2;
x1 = set.find(x1-1);
x2 = set.find(x2-1);
if(x1 == x2) cout << 1;
else cout << 0;
cout << "\n";
}
}
|
cs |
https://www.acmicpc.net/problem/17619
17619번: 개구리 점프
첫 번째 줄에 통나무 개수 N과 질문의 개수 Q가 주어진다. 다음 N개의 줄에 각 통나무에 x1, x2, y의 세 정수 좌표가 주어진다. 주어진 통나무는 두 점 (x1, y)와 (x2, y)를 잇는 형태이다. (x1 < x2) 모든 �
www.acmicpc.net
개구리 점프
통나무들을 x축 위에 나열했을때, x값들이 끊기지 않고 연속적인 값이면, 그 안에 해당되는 통나무끼리 서로 이동이 가능합니다.
따라서 통나무를 표현하는 구조체를 선언하고 해당 구조체 배열에 통나무들을 모두 넣어준다음, 통나무 시작점을 기준으로 sort해주게 되면, 통나무들 끼리의 이어짐 여부를 쉽게 확인할 수 있습니다.
union-find를 이용해서 이어져 있는 통나무 끼리 합쳐주면 서로 다른 두 통나무가 이어져있는지 아닌지 빠른 시간안에 알아낼 수 있습니다.