백준: Class 5 - 2162

1 분 소요


</br> 클래스 5 플레 문제들도 다 풀자
</br>

2162: 선분 그룹

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

#include <bits/stdc++.h>

using namespace std;

pair<int, int> line[2][3001];
int parent[3001];
int ran[3001];

int f(int u){
    if( parent[u] == u ) return u;
    return parent[u] = f(parent[u]);
}

void merg(int u, int v){
    u = f(u); v = f(v);
    if( u == v ) return;
    if( u > v ) swap(u, v);
    parent[v] = u;
    ran[u] += ran[v];
    ran[v] = 0;
}

int sarea(pair<int, int> &a,
          pair<int, int> &b,
          pair<int, int> &c){
    int x1 = a.first;
    int y1 = a.second;
    int x2 = b.first;
    int y2 = b.second;
    int x3 = c.first;
    int y3 = c.second;
    int ret = x2*y1 + x3*y2 + x1*y3 - (x1*y2 + x2*y3 + x3*y1);
    if( ret < 0 ) return 1;
    if( ret == 0 ) return 0;
    return -1;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        line[0][i] = make_pair(x, y);
        cin >> x >> y;
        line[1][i] = make_pair(x, y);
        if( line[0][i] > line[1][i] ) swap(line[0][i], line[1][i]);
        parent[i] = i;
        ran[i] = 1;
    }

    vector<int> v;

    for(int i = 0; i < n-1; i++){
        for(int j = i+1; j < n; j++){
            int iij = sarea(line[0][i], line[1][i], line[0][j]);
            int iijj = sarea(line[0][i], line[1][i], line[1][j]);
            int jji = sarea(line[0][j], line[1][j], line[0][i]);
            int jjii = sarea(line[0][j], line[1][j], line[1][i]);
            if( iij*iijj <= 0 && jji*jjii <= 0 ){
                if( line[0][i] <= line[1][j] && line[0][j] <= line[1][i] ){
                    merg(i, j);
                }
            }
        }
    }

    int cnt = 0, ans = 0;
    for(int i = 0; i < n; i++){
        if( ran[i] ){
            ans = max(ans, ran[i]);
            cnt++;
        }
    }

    cout << cnt << '\n';
    cout << ans << '\n';

}

클래스 5 첫 플레 문제라 긴장했는데 쉬운 문제라 바로 풀이가 생각나고 그대로 구현해서 한 번에 맞았다 다행
일단 선분 교차 판정(https://cyj893.github.io/algorithm/Algorithm17_15/)이 필요하다
n이 3000이라 3000C2 = 4498500으로 다 해 주면 된다
이제 같은 그룹인 지 확인해야 하므로, 유니온 파인드를 쓰자
merg()는 편하게 번호가 작은 순으로 했고, ran[] 배열에 각 부모가 가진 노드들 수를 저장한다
따라서 마지막에 그룹 개수랑 최댓값 구해주면 끝
</br>


이제 두 알고리즘 섞어 쓰고 그런 게 나오는구나
이번 달 바쁘긴 한데 그래도 최대한 많이 풀어야지
</br>

댓글남기기