본문 바로가기
백준/기하

백준 2162 c++ - [PlusUltraCode]

by PlusUltraCode 2024. 2. 19.

[필자 사고]

 

백준 17387번으로 선분의 교차여부를 코드로 작성하였다. 
이 문제는 그에 더해서 Union 알고리즘을 사용하여 문제를 해결할 수 있는지 묻는 문제였다.

먼저 선분의 교차여부 알고리즘을 만들고 Union 알고리즘을 아용하여 그룹의 최대 갯수를 구했다.

 

#include<iostream>
#include <vector>
#include<cmath>
#include <algorithm>

using namespace std;

typedef struct Point {
	long x1, y1, x2, y2;
}Point;

vector<int> parent;
vector<bool> visited;
vector<long> groupCount;
int find(int a) {
	if (a == parent[a])return a;
	else return parent[a] = find(parent[a]);
}

void Union(int a, int b) {
	a = find(a);
	b = find(b);
	if (a != b) {
		parent[b] = a;
	}
}
bool isSame(int a, int b) {
	a = find(a);
	b = find(b);
	if (a == b)return true;
	else return false;
}

int N;
vector<Point> Line;

int CCW(long x1, long y1, long x2, long y2, long x3, long y3) {
	// x1 x2 x3 x1
	// y1 y2 y3 y1
	long ccw = (x1 * y2 + x2 * y3 + x3 * y1) - (x2 * y1 + x3 * y2 + x1 * y3);
	if (ccw == 0)return 0;
	else if (ccw > 0)return 1;
	else return -1;

}
bool isOverlab(Point L1 ,Point L2) {
	long x1 = L1.x1;
	long y1 = L1.y1;
	long x2 = L1.x2;
	long y2 = L1.y2;
	long x3 = L2.x1;
	long y3 = L2.y1;
	long x4 = L2.x2;
	long y4 = L2.y2;

	if (min(x1, x2) <= max(x3, x4) && min(x3, x4) <= max(x1, x2) &&
		min(y1, y2) <= max(y3, y4) && min(y3, y4) <= max(y1, y2)) {
		return true;
	}
	else return false;

}
bool isCross(Point L1, Point L2) {
	long x1 = L1.x1;
	long y1 = L1.y1;
	long x2 = L1.x2;
	long y2 = L1.y2;
	long x3 = L2.x1;
	long y3 = L2.y1;
	long x4 = L2.x2;
	long y4 = L2.y2;
	long abc = CCW(x1, y1, x2, y2, x3, y3);
	long abd = CCW(x1, y1, x2, y2, x4, y4);
	long cda = CCW(x3, y3, x4, y4, x1, y1);
	long cdb = CCW(x3, y3, x4, y4, x2, y2);
	if (abc * abd == 0 && cda * cdb==0) {
		if (isOverlab(L1, L2)) {
			return true;
		}
	}
	else if (abc * abd <= 0 && cda * cdb <= 0)return true;
	return false;

}


void Input() {
	cin >> N;
	Line.resize(N + 1);
	parent.resize(N );
	visited.resize(N,false);
	groupCount.resize(N);
	for (int i = 0; i < N; i++) {
		parent[i] = i;
	}
	for (int i = 0; i < N; i++) {
		long a, b, c, d;
		cin >> a >> b >> c >> d;
		Line[i].x1 = a;
		Line[i].y1 = b;
		Line[i].x2 = c;
		Line[i].y2 = d;
	}

}

void Solve() {
	for (int i = 0; i < N-1; i++) {
		for (int k = i+1; k < N; k++) {
			if (isCross(Line[i], Line[k])) {
				Union(i, k);
			}
		}
	}
	for (int i = 0; i < N; i++) {
		int n = find(i);
	}
	
	for (int i = 0; i < N; i++) {
		groupCount[parent[i]]++;
	}
	long maxNumber = *max_element(groupCount.begin(), groupCount.end());
	long Group = 0;
	for (int i = 0; i < N; i++) {
		if (groupCount[i] != 0) {
			Group++;
		}
	}
	cout << Group << '\n' << maxNumber;
	
}


int main(void) {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	Input();
	Solve();



}

'백준 > 기하' 카테고리의 다른 글

백준 2166 c++ -[PlusUltraCode]  (0) 2024.02.19
백준 17387 c++ -선분 교차2 [PlusUltraCode]  (0) 2024.02.16
백준 11758 c++ -PlusUltraCode  (0) 2024.02.15
기하 개념정리  (0) 2024.02.15