백준 24491 - Searching for Soulmates
2025/01/13
NEW POST
Jinsoolve.
Categories
Tags
1월 안에는 꼭...
About
껍질에 있는 점들을 대상으로 임의의 대각선에 대해서 해당 대각선에서 가장 먼 점 2개를 고르면 해당 대각선으로 만들 수 있는 가장 큰 영역이다. 이때 먼점 2개는 대각선을 기준으로 서로 다른 영역에 있음을 가정한다.
1#include <bits/stdc++.h> 2 3#define endl "\n" 4#define all(v) (v).begin(), (v).end() 5#define all1(v) (v).begin()+1, (v).end() 6#define For(i, a, b) for(int i=(a); i<(b); i++) 7#define FOR(i, a, b) for(int i=(a); i<=(b); i++) 8#define Bor(i, a, b) for(int i=(a)-1; i>=(b); i--) 9#define BOR(i, a, b) for(int i=(a); i>=(b); i--) 10#define ft first 11#define sd second 12 13using namespace std; 14using ll = long long; 15using lll = __int128_t; 16using ulll = __uint128_t; 17using ull = unsigned long long; 18using ld = long double; 19using pii = pair<int, int>; 20using pll = pair<ll, ll>; 21using ti3 = tuple<int, int, int>; 22using tl3 = tuple<ll, ll, ll>; 23 24template<typename T> using ve = vector<T>; 25template<typename T> using vve = vector<vector<T>>; 26 27template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; } 28template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } 29 30const int INF = 987654321; 31const int INF0 = numeric_limits<int>::max(); 32const ll LNF = 987654321987654321; 33const ll LNF0 = numeric_limits<ll>::max(); 34 35struct Point { 36 ll x, y; 37 38 Point() {} 39 Point(ll _x, ll _y) : x(_x), y(_y) {} 40 ll cross(Point other) { 41 return x*other.y - y*other.x; 42 } 43 ll crossSign(Point other) { 44 ll res = this->cross(other); 45 if(res > 0) return 1; 46 else if(res < 0) return -1; 47 return 0; 48 } 49 ll dist(Point other) { 50 return pow(x-other.x,2) + pow(y-other.y,2); 51 } 52 Point operator-(Point other) const { 53 return Point(x-other.x, y-other.y); 54 } 55 bool operator==(Point other) const { 56 return x == other.x && y == other.y; 57 } 58 bool operator<(Point other) const { 59 if(x == other.x) return y < other.y; 60 return x < other.x; 61 } 62 void print() { 63 cout << x << ' ' << y << ' '; 64 } 65}; 66 67Point reference; 68 69vector<Point> Graham_Scan(vector<Point> &points) { 70 sort(all(points)); points.erase(unique(all(points)), points.end()); 71 reference = points[0]; 72 auto cmp = [&](Point a, Point b) { 73 ll res = (a - reference).cross(b - reference); 74 if(res != 0) return res > 0; 75 return reference.dist(a) < reference.dist(b); 76 }; 77 sort(points.begin()+1, points.end(), cmp); 78 79 vector<Point> convex; 80 for(Point p3 : points) { 81 while(convex.size() >= 2) { 82 Point p2 = convex.back(); 83 Point p1 = convex[convex.size() - 2]; 84 ll ccw = (p2-p1).cross(p3-p2); 85 if(ccw > 0) break; 86 convex.pop_back(); 87 } 88 convex.emplace_back(p3); 89 } 90 return convex; 91} 92 93ll triangle(Point &p1, Point &p2, Point &p3) { 94 ll res = abs(p1.x*p2.y + p2.x*p3.y + p3.x*p1.y - p2.x*p1.y - p3.x*p2.y - p1.x*p3.y); 95// if(res % 2 == 0) return (ld)((ll)(res/2)); 96// return (ld)((ll)(res/2) + 0.5); 97 return res; 98} 99 100int n; 101ve<Point> v; 102 103void solve() { 104 cin >> n; 105 ve<Point>tmp(n); 106 For(i,0,n) cin >> tmp[i].x >> tmp[i].y; 107 v = Graham_Scan(tmp); 108 109// for(auto x:v) { 110// x.print(); 111// cout << endl; 112// } 113 114 n = v.size(); 115 if(n == 3) { 116 ll res = triangle(v[0], v[1], v[2]); 117 if(res%2 == 0) cout << res/2 << endl; 118 else cout << res/2 << ".5\n"; 119 return; 120 } 121 122 123 ll ret = 0; 124 For(i,0,n) { 125 int a=(i+1)%n, b=(i+3)%n; 126 For(j, i+2, n) { 127 while(true) { 128 int na = (a+1)%n; 129 if(na == j) break; 130 if(triangle(v[i], v[j], v[a]) < triangle(v[i], v[j], v[na])) a = na; 131 else break; 132 } 133 while(true) { 134 int nb = (b+1)%n; 135 if(nb == i) break; 136 if(triangle(v[i],v[j],v[b]) < triangle(v[i],v[j],v[nb])) b = nb; 137 else break; 138 } 139 ckmax(ret, triangle(v[i],v[j],v[a]) + triangle(v[i],v[j],v[b])); 140 } 141 142 } 143 144 if(ret%2 == 0) cout << ret/2 << endl; 145 else cout << ret/2 << ".5\n"; 146} 147 148int main(void) { 149 ios_base::sync_with_stdio(false); 150 cin.tie(nullptr); 151 cout.tie(nullptr); 152 153 cout << fixed << setprecision(1); 154 155 int TC=1; 156 cin >> TC; 157 FOR(tc, 1, TC) { 158// cout << "Case #" << tc << ": "; 159 solve(); 160 } 161 162 163 return 0; 164}