ACM模板库

ACM模板库


向量

<pre><code class="language-cpp">#include &lt;bits/stdc++.h&gt; using namespace std; const double eps = 1e-8; const int maxn = 1e5+6; int sgn(double x){ if(fabs(x) &lt; eps) return 0; if(x &lt; 0) return -1; else return 1; } struct Point{ double x, y; Point(double _x = 0, double _y = 0){ x = _x; y = _y; } }; //两点距离 double distance(Point p1,Point p2){ return sqrt((p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y)); } typedef Point Vector; //向量相加 A+B Vector operator+(Vector A, Vector B){ return Vector(A.x + B.x, A.y + B.y); } //向量相加 A-B Vector operator-(Vector A, Vector B){ return Vector(A.x - B.x, A.y - B.y); } //向量*数 Vector operator*(Vector A, double p){ return Vector(A.x * p, A.y * p); } //向量点乘 double operator*(Vector A, Vector B){ return A.x * B.x + A.y * B.y; } //向量差乘的长度 double operator^(Vector A, Vector B){ return A.x * B.y - A.y * B.x; } //向量/数 Vector operator/(Vector A, double p){ return Vector(A.x / p, A.y / p); } //向量长度平方 double length2(const Vector &amp;A){ return A.x * A.x + A.y * A.y; } //向量长度 double length(const Vector &amp;A){ return sqrt(A.x * A.x + A.y * A.y); } bool cmp1(const Point &amp;A,const Point &amp;B) { return sgn(A.y - B.y) &lt; 0 || ((sgn(A.y-B.y) == 0 &amp;&amp; sgn(A.x-B.x) &lt; 0)); } //极角排序,角度相同的则距离小的在前面 bool cmp2(const Point &amp;A, const Point &amp;B){ return sgn(A ^ B) &gt; 0 || (sgn(A ^ B) == 0 &amp;&amp; sgn(length(A) - length(B)) &lt; 0); } struct Line{ Point a, b; Line(Point _a = Point(0, 0), Point _b = Point(0, 0)){ a = _a; b = _b; } }; //两直线交点(前提是平行) Point intersection(Line u, Line v){ Point ret = u.a; double t = ((u.a.x-v.a.x)*(v.a.y-v.b.y) - (u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y) - (u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x += (u.b.x-u.a.x) * t; ret.y += (u.b.y-u.a.y) * t; return ret; } //判断点是否在直线上 bool online(Point p, Line l){ return !sgn((p-l.a) ^ (p-l.b)) &amp;&amp; sgn((p-l.a) * (p-l.b)) &lt; 0; } typedef Line Segment; typedef vector&lt;Point&gt; Poly; //求出多边形 lst的凸包,放在ans里面 void graham(Poly &amp;lst, Poly &amp;ans){ sort(lst.begin(), lst.end(), cmp1); Point bs = lst[0]; static vector&lt;int&gt; stk; stk.clear(); stk.push_back(0); for(int i = 0; i &lt; lst.size(); i++) lst[i] = lst[i] - bs; Poly::iterator p = lst.begin(); p++; sort(p, lst.end(), cmp2);//极角排序 for(int i = 1; i &lt; lst.size(); i++){ while(stk.size() &gt; 1 &amp;&amp; sgn((lst[i]-lst[stk[stk.size()-2]]) ^ (lst[stk.back()]-lst[stk[stk.size()-2]])) &gt;= 0) stk.pop_back(); stk.push_back(i); } for(int i = 0; i &lt; stk.size(); i++) ans.push_back(lst[stk[i]] + bs); return; } //求出多边形A和B的闵可夫斯基和,放在ans里面 void minkowski(Poly &amp;A, Poly &amp;B, Poly &amp;ans){ //求闵可夫斯基和 static Poly v1, v2; v1.clear(), v2.clear(); for(int i = 0; i &lt; A.size()-1; i++) v1.push_back(A[i+1] - A[i]); for(int i = 0; i &lt; B.size()-1; i++) v2.push_back(B[i+1] - B[i]); v1.push_back(A[0] - A.back()), v2.push_back(B[0] - B.back()); ans.push_back(A[0] + B[0]); int p1 = 0, p2 = 0; while(p1 &lt; v1.size() &amp;&amp; p2 &lt; v2.size()){ if(sgn(v1[p1] ^ v2[p2]) &gt;= 0) ans.push_back(ans.back() + v1[p1++]); else ans.push_back(ans.back() + v2[p2++]); } while(p1 &lt; v1.size()) ans.push_back(ans.back() + v1[p1++]); while(p2 &lt; v2.size()) ans.push_back(ans.back() + v2[p2++]); } //判断点在多边形内(凸包内) bool in(Poly &amp;P, Point a){ if(sgn((a-P[0]) ^ (P[1]-P[0])) &gt; 0 || sgn((P.back()-P[0]) ^ (a-P[0])) &gt; 0) return false; if(online(a, Line(P[0], P[1])) || online(a, Line(P[0], P.back()))) return true; int l = 1, r = P.size()-2; while(l &lt; r){ int mid= (l+r+1) &gt;&gt; 1; if(sgn((a-P[0]) ^ (P[mid]-P[0])) &gt; 0) r = mid - 1; else l=mid; } return sgn((a-P[r]) ^ (P[r+1]-P[r])) &lt;= 0; } Poly A, B, AA, BB; int main(){ int n,m,q; scanf("%d%d%d",&amp;n,&amp;m,&amp;q); for(int i=1;i&lt;=n;i++){ Point a; scanf("%lf%lf",&amp;a.x,&amp;a.y); A.push_back(a); } graham(A, AA); for(int i=1;i&lt;=m;i++){ Point a; scanf("%lf%lf",&amp;a.x,&amp;a.y); a.x=-a.x; a.y=-a.y; B.push_back(a); } graham(B, BB); A = AA, B = BB; // for(int i = 0; i &lt; BB.size(); i++) cout &lt;&lt; "(" &lt;&lt; BB[i].x &lt;&lt; " " &lt;&lt; BB[i].y &lt;&lt; ")" &lt;&lt; endl; AA.clear(); BB.clear(); minkowski(A,B,AA); graham(AA, BB); while(q--){ Point t; scanf("%lf%lf",&amp;t.x,&amp;t.y); printf("%d\n",in(BB,t)); } return 0; } </code></pre>

页面列表

ITEM_HTML