宜中資訊
CP
Ccucumber12
2021.08.25
using GT = long long ; struct Pt { GT x, y ; Pt operator+(const Pt b) const { return Pt{x+b.x, y+b.y} ; } Pt operator-(const Pt b) const { return Pt{x-b.x, y-b.y} ; } Pt operator*(const GT b) const { return Pt{x*b, y*b} ; } Pt operator/(const GT b) const { return Pt{x/b, y/b} ; } bool operator==(const Pt b) const { return x == b.x && y == b.y ; } double len () { return sqrt(x*x + y*y) ; } GT norm () { return x*x + y*y ; } };
GT dot(Pt a, Pt b) { return a.x * b.x + a.y * b.y ; } GT cross(Pt a, Pt b) { return a.x * b.y - a.y * b.x ; }
int ori(Pt a, Pt b) { GT ret = cross(a, b) ; if(ret == 0) return 0 ; return ret < 0 ? -1 : 1 ; }
多邊形面積
bool in_segment(Pt a, Pt b, Pt p){ return ori(b-a, p-a) == 0 && dot(p-a, p-b) <= 0 ; }
bool banana(Pt a, Pt b, Pt c, Pt d) { if( in_segment(a, b, c) || in_segment(a, b, d) || in_segment(c, d, a) || in_segment(c, d, b)) return true ; return ori(b-a, c-a) * ori(b-a, d-a) < 0 && ori(d-c, a-c) * ori(d-c, b-c) < 0 ; }
bool cmp(Pt a, Pt b) { return atan2(a.x, a,y) < atan2(b.x, b.y) ; }
bool cmp(Pt a, Pt b) { bool f1 = a.x < 0 || (a.x == 0 && a.y < 0) ; bool f2 = b.x < 0 || (b.x == 0 && b.y < 0) ; if(f1 != f2) return f1 < f2 ; return cross(a, b) > 0 ; }
vector<Pt> convex(vector<Pt> v){ vector<Pt> ret ; sort(v.begin(), v.end()) ; int k = 0 ; for(auto i:v){ while(k >= 2 && ori(ret[k-1] - ret[k-2], i - ret[k-1]) <= 0) ret.pop_back(); ret.push_back(i) ; ++k ; } v.pop_back(); int hf = --k ; reverse(v.begin(), v.end()); for(auto i:v){ while(k - hf >= 2 && ori(ret[k-1] - ret[k-2], i - ret[k-1]) <= 0) ret.pop_back(); ret.push_back(i) ; ++k ; } return ret; }