Posts 3108 logo
Post
Cancel

3108 logo

알고리즘

  • 겹치는 사각형을 각기 다른 집합으로 분류 + (0,0) 점이 속하는 집합이 있는지 확인
  • 앞에서부터 겹치는 사각형을 확인하고, 겹치면, 큐의 맨 앞에 넣어서 DFS 방식으로 집합을 분류
  • 매번 모든 사각형을 검사하는데, 이미 분류된 사각형은 다시 검사하지 않아도 됨.
  • 이때 (0,0,0,0)인 사각형(사실은 점)을 1개 더 저장하여, 검사할때 이 점도 검사하도록 하여, 클래스가 분류되면, 원점이 속하는 집합이 있는거고, 분류되지 않으면 없는 것이니, 이것으로 최종 결과를 계산함.

코드

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
#include <iostream>
#include <cstring>
#include <list>
using namespace std;

int N, point[1001][4], classes[1001], classCount;
bool check[1000];
list<int> q;

void classify();
void countClass();

int main() {
	memset(classes, -1, sizeof(classes));

	cin >> N;
	for (int i = 0; i < N; i++)
		cin >> point[i][0] >> point[i][1] >> point[i][2] >> point[i][3];

	classify();
	countClass();

	for (int i = 0; i < N + 1; i++) {
		cout << classes[i] << " ";
	}
	cout << endl;

	if (classes[N] == -1)
		cout << classCount;
	else
		cout << classCount - 1;
}

void classify() {
	int nextClass = 0;

	for (int i = 0; i < N; i++)
		q.push_back(i);

	while(!q.empty()) {
		int i = q.front();
		q.pop_front();

		if (classes[i] == -1)
			classes[i] = nextClass++;

		int x1 = point[i][0], x2 = point[i][2], y1 = point[i][1], y2 = point[i][3];
		int iline[4][4] = { {x1, y2, x2, y2}, {x2, y1, x2, y2},{x1, y1, x2, y1},{x1, y1, x1, y2} }; // 위 오 아 왼

		for (int j = 0; j < N + 1; j++) {
			if (classes[j] != -1)
				continue;
			bool same = false;

			x1 = point[j][0], x2 = point[j][2], y1 = point[j][1], y2 = point[j][3];
			int jline[4][4] = { {x1, y2, x2, y2}, {x2, y1, x2, y2},{x1, y1, x2, y1},{x1, y1, x1, y2} };

			for (int k = 0; k < 4; k++) {
				for (int p = 0; p < 4; p++) {
					if (k % 2 == 0 && p % 2 == 0 && iline[k][1] == jline[p][1] && !(iline[k][0] > jline[p][2] || iline[k][2] < jline[p][0]))
						same = true;
					else if (k % 2 == 1 && p % 2 == 1 && iline[k][0] == jline[p][0] && (!(iline[k][1] > jline[p][3] || iline[k][3] < jline[p][1])))
						same = true;
					else if (k % 2 == 0 && !(iline[k][0] > jline[p][0] || iline[k][2] < jline[p][0] || iline[k][1] > jline[p][3] || iline[k][1] < jline[p][1]))
						same = true;
					else if (!(iline[k][0] > jline[p][2] || iline[k][0] < jline[p][0] || iline[k][1] > jline[p][3] || iline[k][3] < jline[p][1]))
						same = true;
				}
			}
			if (same) {
				classes[j] = classes[i];
				q.push_front(j);
			}
		}
	}
}

void countClass() {
	for (int i = 0; i < N; i++) {
		if (!check[classes[i]]) {
			check[classes[i]] = true;
			classCount++;
		}
	}
}
This post is licensed under CC BY 4.0 by the author.

1039 교환

Graph ql back

Comments powered by Disqus.