문제: icpc.me/2254
점(Px,py)를 감싸는 볼록껍질이 최대 몇개까지 가능한지 묻는 문제이다.
기둥들로 Convex hull을 구해준 뒤 해당 껍질이 Px,Py를 감싸는지 ccw로 확인해준 뒤 해당 Convex hull을 이루는 요소들을 전부 지워 준 뒤 이를 반복하여 점(Px,Py)를 감싸는 껍질의 수를 구해준다.
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #include <cstdio> #include <algorithm> #include <stack> #include <vector> #include <cstring> using namespace std; struct dot { double x, y; double p, q; dot() { p = 0.0, q = 0.0; }; dot(double x, double y) :x(x), y(y) { p = 0.0, q = 0.0; } int getccw(dot a, dot b) { double tmp = this->x*a.y + a.x*b.y + b.x*this->y - this->y*a.x - a.y*b.x - b.y*this->x; if (tmp > 0)return 1; else if (tmp == 0)return 0; else return -1; } bool operator<(const dot &d) { if (q*d.p != p*d.q)return q*d.p < p*d.q; return y == d.y ? x < d.x : y < d.y; } }; int n, r; double px, py; int chk[1010]; vector<dot> d; dot pp; bool getConvexHull() { memset(chk, 0, sizeof(chk)); stack<int> st; st.push(0), st.push(1); int next = 2; while (next < d.size()) { while (st.size() >= 2) { int one, two; one = st.top(); st.pop(); two = st.top(); if (d[two].getccw(d[one], d[next])>0) { st.push(one); break; } } st.push(next++); } bool ret = st.size() > 2 ? 1 : 0; vector<int> vt; while (st.size()) { vt.push_back(st.top()); st.pop(); } int dft = pp.getccw(d[vt[vt.size() - 1]], d[vt[0]]); bool f = 0; for (int i = 0; i < vt.size() - 1; i++) { if (dft != pp.getccw(d[vt[i]], d[vt[i + 1]])) { f = 1; break; } } if (!f)r++; for (auto next : vt) { chk[next] = 1; } vector<dot> tmp; for (int i = 0; i < d.size(); i++) { if (!chk[i]) tmp.push_back(d[i]); } d.clear(); for (auto next : tmp) d.push_back(next); return ret; } void getslope() { sort(d.begin(), d.end()); for (int i = 0; i < d.size(); i++) { d[i].p = d[i].x - d[0].x; d[i].q = d[i].y - d[0].y; } auto it = d.begin(); it++; sort(it, d.end()); } int main() { scanf("%d%lf%lf", &n, &px, &py); pp = dot(px, py); for (int i = 0; i < n; i++) { double x, y; scanf("%lf%lf", &x, &y); d.push_back(dot(x, y)); } while (1) { if (d.size() < 3)break; getslope(); bool c = getConvexHull(); if (!c)break; } printf("%d\n", r); return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)14577 일기예보 (0) | 2017.06.04 |
---|---|
BOJ)6850 Cows (0) | 2017.06.02 |
BOJ)5670 휴대폰 자판 (0) | 2017.05.30 |
BOJ)5624 좋은 수 (0) | 2017.05.17 |
BOJ)12961 체스판2 (0) | 2017.05.17 |