Https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/E
Test instructions
Given the coordinates of n points, you can choose four points to construct a convex quadrilateral, and how many convex quads can be constructed at most?
Ideas
The number of convex quads equals the number of C (n,4)-concave quadrilateral shapes.
The concave quadrilateral is characterized by the addition of a vertex to a triangle surrounded by another three vertices.
So now the problem is to find concave quadrilateral.
We can enumerate each point as the center point that is surrounded by triangles o. How do you find the triangle that surrounds the center point?
Such a triangle must be in existence a straight line through the center point, the three vertices of the triangle on the same side of the line.
Then one vertex x of the triangle is enumerated, and the other two vertices must be within the upper half of the line of the Ox, O and X. And doing so is similar to taking a ruler, just the complexity of O (n).
The last thing to note is:
printf ("%i64d\n", -3ll*n* (n-1) * (n-2) * (n-3)/24+cnt);
printf ("%i64d\n", N (n-1) * (n-2) * (n-3)/24ll-(n (n-1) * (n-2) * (n-3)/6ll-cnt));
The difference.
The former becomes 3LL in front, so the calculation of the multiplication is to convert int to ll, which will not explode
The latter n (n-1) * (n-2) * (n-3) has exploded in the process of calculation.
There are two ways to solve this problem:
Multiply 1ll;n in front into LL
"Accelerate"
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <string>5#include <cmath>6#include <algorithm>7 8 using namespacestd;9typedefLong Longll;Ten Const intmaxn=710; One intN; A ll XX[MAXN]; - ll YY[MAXN]; - intcur; the DoubleDis (ll x1,ll y1,ll x2,ll y2) {returnsqrt ((x1-x2) * (X1-X2) + (y1-y2) * (y1-y2));} - struct Point - { - ll X; + ll y; - Doubledis; + DoubleAlf; A Point () {} at Point (ll _x,ll _y): X (_x), Y (_y) {} -Pointoperator-(ConstPoint &t)Const - { - returnPoint (x-t.x,y-t.y); - } -lloperator^(ConstPoint &t)Const in { - return(X*T.Y)-(y*t.x); to } + Doublealfa () - { the if(Y>yy[cur])returnACOs ((X-xx[cur])/dis); * return-acos ((X-xx[cur])/dis); $ }Panax Notoginseng }P[MAXN]; - the BOOLCMP (point a,point B) + { A if(b.x==xx[cur]&&b.y==Yy[cur]) the { + return true; - } $ if(a.x==xx[cur]&&a.y==Yy[cur]) $ { - return false; - } the returna.alf<b.alf; - }Wuyi the intMain () - { Wu intT; -scanf"%d",&T); About while(t--) $ { -scanf"%d",&n); - for(intI=0; i<n;i++) - { ACin>>xx[i]>>Yy[i]; +p[i]=Point (Xx[i],yy[i]); the } -ll cnt=0; $ for(cur=0; cur<n;cur++) the { the the intL=1; the Point O (Xx[cur],yy[cur]); - for(intI=0; i<n;i++) {P[i].dis=dis (p[i].x,p[i].y,xx[cur],yy[cur]);p [i].alf=P[i].alfa ();} inSort (p,p+n,cmp); the for(intI=0; i<n-1; i++) the { About while((p[i]-o) ^ (p[l]-o)) >0) the { theL= (L +1)% (n1); the } + intLen= (l-i-1+n-1)% (n1); -cnt+=len* (len-1)/2; the }Bayi } the //ll ans=n* (n-1) * (n-2) * (n-3)/24ll-(n (n-1) * (n-2) * (n-3)/6ll-cnt);//Note that this will explode. the //printf ("%i64d\n", -3ll*n* (n-1) * (n-2) * (n-3)/24+cnt);//the front is multiplied by 3LL and will not explode -printf"%i64d\n", 1ll*n* (n1) * (n2) * (n3)/24ll-(1ll*n* (n1) * (n2) * (n3)/6ll-cnt)); - } the return 0; the}
View Code
"Knowledge points"
Determine whether the cross product is used in a semi-planar nature:
A very important property of the cross product is the determination of the CIS-counterclockwise relationship between two vectors by its symbol: Set vector p= (x1,y1), q= (X2,y2)
If P*q>0 is p in the clockwise direction of Q;
If the p*q=0 p is collinear with Q, it may be in the same direction, with the possible inverse;
If P*q<0 p is in the counterclockwise direction of Q.
"Compute geometry + polar sort + burst ll" E. convex