이 글에서는 주어진 가로선과 세로선의 교차점을 연결하여 만들 수 있는 삼각형의 개수를 찾는 프로그램에 대해 설명합니다.
예를 들어 다음과 같은 선분을 받았다고 가정해 보겠습니다. 여기에는 3개의 교차점이 있습니다. 따라서 이 점을 사용하여 만들 수 있는 삼각형의 수는 3 입니다. C2 .
| ---|--------|-- | | | --|---| | |
우리는 Sweep Line Algorithm을 따를 것입니다. 선분의 모든 값을 저장한 다음 선 중 하나 내부의 점이 다른 선의 내부 점과 비교되는지 확인합니다. 이 방법으로 우리는 주어진 선분에 대한 모든 교차점을 가질 수 있고 다른 가능한 조합을 사용하여 가능한 삼각형의 수를 쉽게 찾을 수 있습니다.
예시
#include<bits/stdc++.h> #define maxy 1000005 #define maxn 10005 using namespace std; //to store intersection points struct i_point { int x, y; i_point(int a, int b) { x = a, y = b; } }; int bit[maxy]; vector < pair <i_point, int> > events; //to sort the given points bool com_points(pair<i_point, int> &a, pair<i_point, int> &b) { if ( a.first.x != b.first.x ) return a.first.x < b.first.x; else { if (a.second == 3 && b.second == 3) { return true; } else if (a.second == 1 && b.second == 3) { return true; } else if (a.second == 3 && b.second == 1) { return false; } else if (a.second == 2 && b.second == 3) { return false; } return true; } } void topdate_line(int index, int value) { while (index < maxn) { bit[index] += value; index += index & (-index); } } int query(int index) { int res = 0; while (index > 0) { res += bit[index]; index -= index & (-index); } return res; } //to insert a line segment void insertLine(i_point a, i_point b) { //in case of horizontal line if (a.y == b.y) { int begin = min(a.x, b.x); int end = max(a.x, b.x); events.push_back(make_pair(i_point(begin, a.y), 1)); events.push_back(make_pair(i_point(end, a.y), 2)); } //in case of vertical line else { int top = max(b.y, a.y); int bottom = min(b.y, a.y); events.push_back(make_pair(i_point(a.x, top), 3)); events.push_back(make_pair(i_point(a.x, bottom), 3)); } } //to calculate number of intersection points int calc_i_points() { int i_points = 0; for (int i = 0 ; i < events.size() ; i++) { if (events[i].second == 1) { topdate_line(events[i].first.y, 1); } else if (events[i].second == 2) { topdate_line(events[i].first.y, -1); } else { int bottom = events[i++].first.y; int top = events[i].first.y; i_points += query(top) - query(bottom); } } return i_points; } int calc_triangles() { int points = calc_i_points(); if ( points >= 3 ) return ( points * (points - 1) * (points - 2) ) / 6; else return 0; } int main() { insertLine(i_point(3, 2), i_point(3, 13)); insertLine(i_point(1, 5), i_point(3, 5)); insertLine(i_point(8, 2), i_point(8, 8)); insertLine(i_point(3, 4), i_point(6, 4)); insertLine(i_point(4, 3), i_point(4, 5)); sort(events.begin(), events.end(), com_points); cout << "Possible number of triangles : " << calc_triangles() << endl; return 0; }
출력
Possible number of triangles : 1