241004 선분 그룹

Jongleee·2024년 10월 4일
0

TIL

목록 보기
695/737
public static void main(String[] args) throws IOException {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	int n = Integer.parseInt(br.readLine());

	int[][] segments = new int[n + 1][4];
	int[] parent = new int[n + 1];

	for (int i = 1; i <= n; i++) {
		parent[i] = i;
	}

	for (int i = 1; i <= n; i++) {
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		segments[i][0] = Integer.parseInt(st.nextToken());
		segments[i][1] = Integer.parseInt(st.nextToken());
		segments[i][2] = Integer.parseInt(st.nextToken());
		segments[i][3] = Integer.parseInt(st.nextToken());
	}

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j < i; j++) {
			if (doIntersect(segments[i], segments[j])) {
				union(i, j, parent);
			}
		}
	}

	int[] count = new int[n + 1];
	for (int i = 1; i <= n; i++) {
		count[find(i, parent)]++;
	}

	int groups = 0;
	int maxGroupSize = 0;
	for (int i = 1; i <= n; i++) {
		if (count[i] > 0) {
			groups++;
			if (count[i] > maxGroupSize) {
				maxGroupSize = count[i];
			}
		}
	}

	System.out.println(groups);
	System.out.println(maxGroupSize);
}

private static int ccw(int ax, int ay, int bx, int by, int cx, int cy) {
	long value = (long) (ax) * by + (long) (bx) * cy + (long) (cx) * ay
			- (long) (ay) * bx - (long) (by) * cx - (long) (cy) * ax;
	if (value > 0)
		return 1;
	if (value < 0)
		return -1;
	return 0;
}

private static boolean doIntersect(int[] seg1, int[] seg2) {
	int ax = seg1[0];
	int ay = seg1[1];
	int bx = seg1[2];
	int by = seg1[3];
	int cx = seg2[0];
	int cy = seg2[1];
	int dx = seg2[2];
	int dy = seg2[3];

	int ccw1 = ccw(ax, ay, bx, by, cx, cy);
	int ccw2 = ccw(ax, ay, bx, by, dx, dy);
	int ccw3 = ccw(cx, cy, dx, dy, ax, ay);
	int ccw4 = ccw(cx, cy, dx, dy, bx, by);

	if (ccw1 * ccw2 <= 0 && ccw3 * ccw4 <= 0) {
		if (ccw1 == 0 && ccw2 == 0) {
			return isOverlapping(seg1, seg2);
		}
		return true;
	}
	return false;
}

private static boolean isOverlapping(int[] seg1, int[] seg2) {
	boolean overlapX = Math.max(seg1[0], seg1[2]) >= Math.min(seg2[0], seg2[2])
			&& Math.max(seg2[0], seg2[2]) >= Math.min(seg1[0], seg1[2]);
	boolean overlapY = Math.max(seg1[1], seg1[3]) >= Math.min(seg2[1], seg2[3])
			&& Math.max(seg2[1], seg2[3]) >= Math.min(seg1[1], seg1[3]);
	return overlapX && overlapY;
}

private static int find(int a, int[] parent) {
	if (a == parent[a]) {
		return a;
	}
	parent[a] = find(parent[a], parent);
	return parent[a];
}

private static void union(int a, int b, int[] parent) {
	int rootA = find(a, parent);
	int rootB = find(b, parent);
	if (rootA != rootB) {
		parent[rootA] = rootB;
	}
}

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

0개의 댓글