반응형
https://www.acmicpc.net/problem/2162
2162번: 선분 그룹
첫째 줄에 N(1 ≤ N ≤ 3,000)이 주어진다. 둘째 줄부터 N+1번째 줄에는 양 끝점의 좌표가 x1, y1, x2, y2의 순서로 주어진다. 각 좌표의 절댓값은 5,000을 넘지 않으며, 입력되는 좌표 사이에는 빈칸이 하
www.acmicpc.net
[ 문제풀이 ]
[ 백준 ] 17387번 - 선분 교차 2 (C++)
https://www.acmicpc.net/problem/17387 17387번: 선분 교차 2 첫째 줄에 L1의 양 끝 점 x1, y1, x2, y2가, 둘째 줄에 L2의 양 끝 점 x3, y3, x4, y4가 주어진다. www.acmicpc.net [ 문제풀이 ] 선분이 교차할..
rudalsd.tistory.com
위 문제를 풀어보고 오는 것을 추천드립니다!
이 문제는 선분 교차 2 문제에서 Union - Find를 추가한 문제입니다. 직선의 개수가 3000개밖에 되지 않으므로 2중 for문을 돌려도 큰 문제가 없으므로 2중 for문으로 문제를 풀었습니다. 선분이 교차한다면 Union을 해주고 마지막에 모든 선분을 돌면서 Find를 통해 map에 부모 노드를 저장해줍니다.
그리고 map.size()와 map[ i ]의 값 중 제일 큰 값을 출력해주면 됩니다.
[ 소스 코드 ]
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 | #include <iostream> #include <algorithm> #include<unordered_map> using namespace std; struct pos { int x; int y; }; pos arr[6000]; int vect[3001]; unordered_map<int, int> m; int N; int Find(int n) { if (vect[n] == n) return n; return vect[n] = Find(vect[n]); } void Union(int a, int b) { int pa = Find(a); int pb = Find(b); if (pa != pb) { vect[pb] = pa; } } bool cmp(pos left, pos right) { if (left.x == right.x) return left.y <= right.y; return left.x <= right.x; } int closs(pos p1, pos p2, pos p3) { //외적을 통해 방향을 리턴 int cross_product = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y); if (cross_product > 0) { return 1; } else if (cross_product < 0) { return -1; } else { return 0; } } int main() { cin >> N; for (int i = 0; i < N * 2; i++) { cin >> arr[i].x >> arr[i].y; } for (int i = 0; i < N ; i++) { sort(arr + i * 2, arr + (i + 1) * 2, cmp); } for (int i = 0; i < N; i++) { vect[i] = i; } for (int i = 0; i < N - 1; i++) { for (int j = i + 1; j < N; j++) { int l1 = closs(arr[i * 2], arr[i * 2 + 1], arr[j * 2]) * closs(arr[i * 2], arr[i * 2 + 1], arr[j * 2 + 1]); int l2 = closs(arr[j * 2], arr[j * 2 + 1], arr[i * 2]) * closs(arr[j * 2], arr[j * 2 + 1], arr[i * 2 + 1]); if (l1 == 0 && l2 == 0) { //두 선이 일직선상에 있을 때 if (cmp(arr[j*2], arr[i*2+1]) && cmp(arr[i*2], arr[j*2+1])) { if (Find(i) != Find(j)) { Union(i, j); } } } else if (l1 <= 0 && l2 <= 0) { if (Find(i) != Find(j)) { Union(i, j); } } } } for (int i = 0; i < N; i++) { m[Find(i)]++; //집합에 속해있다면 선분을 map에 추가 } int ans = 0; for (auto it = m.begin(); it != m.end(); it++) { if (ans < it->second) { //집합 중 가장 큰 집합을 ans에 대입 ans = it->second; } } cout << m.size() << endl << ans; } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 14725번 - 개미굴 (C++) (0) | 2022.06.28 |
---|---|
[ 백준 ] 2533번 - 사회망 서비스(SNS) (C++) (0) | 2022.06.27 |
[ 백준 ] 2568번 - 전깃줄 - 2 (C++) (0) | 2022.06.25 |
[ 백준 ] 14939번 - 불 끄기 (C++) (0) | 2022.06.24 |
[ 백준 ] 12850번 - 본대 산책2 (C++) (0) | 2022.06.23 |