Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define P(x,y) make_pair(x,y)
- using namespace std;
- typedef vector<int> vi ;
- typedef vector<string> vs ;
- typedef vector<double> vd ;
- #define sz(x) ((int)(x).size())
- #define all(x) x.begin(),x.end()
- #define pb(x) push_back(x)
- #define EPS 1e-11
- #define dot(a,b) ((conj(a)*(b)).real())
- #define cross(a,b) ((conj(a)*(b)).imag())
- typedef complex< long double > point;
- #define X real()
- #define Y imag()
- #define length(a) hypot((a).real(),(a).imag())
- #define length2(a) dot(a,a)
- #define normalize(a) ((a)/length(a))
- #define polar(r,theta) r*exp(point(0,theta))
- #define vect(p1,p2) ((p2)-(p1))
- #define mid(p1,p2) ((p1)+(p2))/point(2,0)
- #define same(a,b) (length2(vect(a,b))<EPS)
- #define angle(a) atan2((a).imag(),(a).real())
- const long double pi = acos(-1);
- int compare(long double d1,long double d2)
- {
- if(fabs(d1-d2) < EPS) return 0;
- if(d1<d2) return -1;
- return 1;
- }
- bool lineIntersect(point a,point b, point p, point q, point& r)
- {
- long double d1 = cross(p-a,b-a);
- long double d2 = cross(q-a,b-a);
- if(fabs(d2-d1)<EPS)
- return false;
- r = (d1*q - d2*p)/ (d1-d2);
- return true;
- }
- bool isPointOnLine(point a,point b, point p) // btgeb eza kan el p 3la el line elle 3lehel 2 points a,b
- {
- return fabs(cross(vect(a,b),vect(a,p)))<EPS;
- }
- bool isPointOnRay(point a,point b, point p) // btgeb eza kan el
- {
- return dot(vect(a,b),vect(a,p))>-EPS && isPointOnLine(a,b,p);
- }
- bool isPointOnSegment(point a,point b, point p) // btgeb eza kan el
- {
- return dot(vect(a,b),vect(a,p))>-EPS && isPointOnLine(a,b,p) && dot(vect(b,a),vect(b,p))>-EPS;
- }
- /*long long double cosineRule(long long double a,long long double b,long long double c) // btgeb el zwya ben el b,c
- {
- long long double x =( b*b + c*c - a*a) / (2*b*c);
- // btgeb el angle elle 2osad el a
- if(x>1)x =1;
- if(x<-1)x=-1;
- return acos(x);
- }*/
- // if we have 2 angels A & B and a side length b this function returns the side length a
- long double sinRuleGetSide(long double A,long double B,long double b)
- {
- return (sin(A)*b)/sin(B);
- }
- // if we have 2 sides lengths a & b and an angel B this function returns the angel A
- long double sinRuleGetAngel(long double a,long double b,long double B)
- {
- long double A=(a*sin(B))/b;
- if(A>1)a=1;
- if(A<-1)a=-1;
- return asin(A);
- }
- // checking intersection
- int isIntersecting(point c1,point c2,long double r1,long double r2)
- {
- // 0 if no intersection
- // 1 if normally intersecting
- // 2 if outside tangent
- // 3 if inside tangent
- // 4 if C1 contain C2
- // 5 if same circule
- if(compare(r1+r2, length(c1-c2))<0) return 0; // no intersection
- if(compare(length(c1-c2),fabs(r1-r2))<0) return 4; // no intersection
- if(length(c1-c2)<EPS && compare(r1,r2) == 0) return 5; // same circule
- if(compare(r1+r2 ,length(c1-c2)) == 0) return 2;
- if(compare(fabs(r1-r2),length(c1-c2))== 0) return 3;
- if(compare(r1+r2,length(c1-c2)) > 0) return 1;
- }
- /*void circuleIntersection(point c1,point c2,long double r1,long double r2,point& p1,point& p2)
- {
- if(r1<r2)
- {
- swap(r1,r2);
- swap(c1,c2);
- }
- long double theta1 = angle(c2-c1); long long double theta2 = cosineRule(r2,r1,length(c2-c1));
- p1 = polar(r1, theta1+theta2)+c1;
- p2 = polar(r1, theta1-theta2)+c1;
- }*/
- bool lineCirculeIntersection(point p0,point p1,point C,long double r,point& r1,point& r2)
- {
- // p0,p1 -> line
- // C,r ->circle
- long double a = dot(p1-p0,p1-p0);
- long double b = 2*dot(p1-p0,p0-C);
- long double c = dot(p0-C,p0-C)- r*r;
- long double x = b*b-(4*a*c);
- if(x<-1*EPS) return false; // law el rkam b negative 3shan ma3mlsh square root l x:D
- if(fabs(x)<EPS) x = 0;
- long double t1 = (-1*b + sqrt(x))/(2*a);
- long double t2 = (-1*b - sqrt(x))/(2*a);
- r1 = p0 + t1*(p1-p0);
- r2 = p0 + t2*(p1-p0);
- return true;
- }
- /*
- For convex HULL
- */
- struct cmp{
- point about;
- cmp(point c)
- {
- about = c;
- }
- bool operator()(const point& p,const point& q)const
- {
- long double cr = cross(vect(about,p),vect(about,q));
- if(fabs(cr)<EPS)
- return make_pair(p.Y,p.X)< make_pair(q.Y,q.X);
- return cr>0;
- }
- };
- vector<point> pnts;
- vector<point> convex;
- void convexHull()
- {
- point mn(1/0.0,1/0.0);
- for(int i = 0 ; i < sz(pnts) ; i++)
- {
- if(make_pair(pnts[i].Y,pnts[i].X) < make_pair(mn.Y,mn.X))
- mn= pnts[i];
- }
- sort(all(pnts),cmp(mn));
- convex.clear();
- convex.push_back(pnts[0]);
- if(sz(pnts)==1)return ;
- convex.push_back(pnts[1]);
- for(int i = 2; i <= sz(pnts) ; i++)
- {
- point c = pnts[i%sz(pnts)];
- while(sz(convex)>1)
- {
- point b = convex.back();
- point a = convex[sz(convex)-2];
- if(cross(vect(b,a),vect(b,c))<-EPS)
- break;
- convex.pop_back();
- }
- if(i<sz(pnts))
- convex.push_back(pnts[i]);
- }
- }
- //to rotate point
- point rotate_by(const point &p, const point &about, long double radians)
- {
- return (p - about) * exp(point(0, radians)) + about;
- }
- //to reflect point
- point reflect(const point &p, const point &about1, const point &about2)
- {
- point z = p - about1;
- point w = about2 - about1;
- return conj(z / w) * w + about1;
- }
- bool testColinearPoints(const point& a,const point& b,const point& c)
- {
- return fabs(cross(b-a,c-b)) < EPS;
- }
- long double pointLineDistance(const point& a,const point& b,const point& p) // ab is the line and other is the point
- {
- return fabs(cross(b-a,p-a))/length(b-a);
- }
- long double pointSegmentDistance(const point& a,const point& b,const point& p)
- {
- if(dot(p-a,b-a)<=0)return length(p-a);
- if(dot(p-b,a-b)<=0)return length(p-b);
- return pointLineDistance(a,b,p);
- }
- enum states{EXTERIOR,INTERIOR,BOUNDARY};
- int inSidePolygon(vector<point> polygon,point p)
- {
- int counter = 0;
- int i;
- long double xinters;
- point p1,p2;
- int N = polygon.size();
- p1 = polygon[0];
- for (i=1;i<=N;i++) {
- p2 = polygon[i % N];
- if (p.Y > min(p1.Y,p2.Y)) {
- if (p.Y <= max(p1.Y,p2.Y)) {
- if (p.X <= max(p1.X,p2.X)) {
- if (p1.Y != p2.Y) {
- xinters = (p.Y-p1.Y)*(p2.X-p1.X)/(p2.Y-p1.Y)+p1.X;
- if (p1.X == p2.X || p.X <= xinters)
- counter++;
- }
- }
- }
- }
- if(pointSegmentDistance(p1,p2,p) == 0) return 2; //point on segment
- p1 = p2;
- }
- if (counter % 2)
- return 1;
- else
- return 0;
- }
- long double polygonArea(vector<point> pol)
- {
- long double res=0;
- pol.push_back(pol[0]);
- for(int i = 0 ; i < (int)pol.size()-1 ; i ++)
- {
- res+=cross(pol[i],pol[i+1]);
- }
- res/=2;
- return res;
- }// if points are given in anti clockwise -> res will be positive else negative
- long double traingleArea(long double a,long double b, long double c)// heron's formula
- {
- long double s = (a+b+c)/2;
- return sqrt(s*(s-a)*(s-b)*(s-c));
- }
- pair<point,double> getCircle2(point a, point b) // el long double el awalane el center we el tane el raduis
- {
- // a, b are diameter(kotr)
- return make_pair((a+b)/point(2,0),length(b-a)/2);
- }
- pair<point,double> getCircle3(point a, point b, point c) // el long double el awalane el center we el tane el raduis
- {
- point v1 = vect(a,b);
- point mid1 =(b+a)/point(2,0);
- point p1 (-1*v1.Y,v1.X);
- p1+=mid1;
- point v2 = vect(b,c);
- point mid2 = (c+b)/point(2,0);
- point p2(-1*v2.Y,v2.X);
- p2+= mid2;
- point C;
- lineIntersect(mid1,p1,mid2,p2,C);
- return make_pair(C,length(C-a));
- }
- // minimum enclosing circle
- // random_shuffle(pnts.begin(),pnts.end()); lazem shuffle 2bl el ms2la 3shan at2kd en hya htege fe n
- #define MAXSIZE 100
- int ps = 0,rs = 0;
- point pts[MAXSIZE],rem[3];
- pair<point,double> cir;
- void mec()
- {
- if(rs==3)
- {
- cir= getCircle3(rem[0],rem[1],rem[2]);
- return;
- }
- if(ps == 0)
- {
- if(rs==2)
- cir = getCircle2(rem[0],rem[1]);
- else
- cir = make_pair(rem[0],0);
- return ;
- }
- ps--;
- mec();
- if(length2(vect(pts[ps],cir.first))>cir.second*cir.second){
- rem[rs++]=pts[ps];
- mec();
- rs--;
- }
- ps++;
- }
- long double circumference(long double r)
- {
- return 2*pi*r;
- }
- void polygonCut(vector<point>& input, vector<point>& res,const point& a,const point& b)//input is anti clockwise
- {
- // take care of removing duplicate points
- res.clear();
- point p,q;
- for(int i= 0 ; i < sz(input) ; i ++)
- {
- p = input[i];
- q = input[(i+1)%sz(input)];
- bool b1,b2;
- b1 = cross(vect(a,b),vect(a,p))> -EPS;
- b2 = cross(vect(a,b),vect(a,q))> -EPS;
- if(b1)
- res.push_back(p);
- if(b1^b2)
- {
- point r;
- lineIntersect(b,a,p,q,r);
- res.push_back(r);
- }
- }
- }
- void convexPolygonIntersection(vector<point> p1,vector<point> p2,vector<point>& res)
- {
- vector<point> temp ;
- res= p1;
- point p,q;
- for(int i = 0 ; i < sz(p2) ; i++)
- {
- p = p2[i];
- q = p2[(i+1)%sz(p2)];
- polygonCut(res,temp,p,q);
- res = temp;
- }
- }
- void voronoi(vector<point> inp, long double xmn,long double ymn,long double xmx,long double ymx,vector<vector<point> >& res)
- {
- res.clear();
- point p,q;
- vector<point> tmp2;
- for(int i = 0 ; i < sz(inp) ; i ++)
- {
- vector<point> tmp;
- tmp.push_back(point(xmn,ymn));
- tmp.push_back(point(xmx,ymn));
- tmp.push_back(point(xmx,ymx));
- tmp.push_back(point(xmn,ymx));
- p = inp[i];
- for(int j = 0 ; j < sz(inp) ; j++)
- {
- if(i==j)continue;
- q = inp[j];
- point k = mid(p,q);
- point pq = vect(p,q);
- point prb = point(-pq.Y,pq.X);
- polygonCut(tmp,tmp2,k,k+prb);
- tmp = tmp2;
- }
- res.push_back(tmp);
- }
- }
- // TAKE CARE this function fails if polygon intersects with itself
- // return the centroid point of the polygon
- // The centroid is also known as the "centre of gravity" or the "center of mass". The position of the centroid
- // assuming the polygon to be made of a material of uniform density.
- point polygin_centroid(vector<point> &polygon)
- {
- pair < long double , long double > res;
- long double a = 0;
- //res.X += 9.0;
- for( int i= 0 ; i < sz(polygon) ; i++ )
- {
- int j = (i+1) % sz(polygon);
- res.first += (polygon[i].X + polygon[j].X)* (polygon[i].X * polygon[j].Y - polygon[j].X * polygon[i].Y);
- res.second += (polygon[i].Y+polygon[j].Y)* (polygon[i].X * polygon[j].Y - polygon[j].X * polygon[i].Y);
- a += polygon[i].X * polygon[j].Y - polygon[i].Y * polygon[j].X;
- }
- a *= 0.5;
- res.first /= (6.0 * a);
- res.second /= (6.0 * a);
- return point(res.first , res.second);
- }
- const int MX=(1<<20);
- point p[MX];
- int n;
- vector < int > v;
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("in.in","r",stdin);
- #endif // ONLINE_JUDGE
- cin>>n;
- for(int j=1;j<=n;j++){
- int a , b;
- scanf("%d %d",&a,&b);
- p[j] = point(a,b);
- }
- int a = 1 , b = 2;
- for(int j=3;j<=n;j++){
- if(testColinearPoints(p[a] , p[b] , p[j])){
- if(compare(length(vect(p[a] , p[b])) , length(vect(p[a] , p[j]))) == 1)
- b=j;
- }
- }
- long double mn = 1e50;
- int c=100;
- for(int j=1;j<=n;j++){
- if(j==a || j==b) continue;
- if(testColinearPoints(p[a] , p[b] , p[j])) {
- // puts("sex");
- continue;
- }
- vector < point > P;
- P.push_back(p[a]);
- P.push_back(p[b]);
- P.push_back(p[j]);
- long double area = traingleArea(length(vect(p[a] , p[b])) , length(vect(p[a] , p[j])) , length(vect(p[j] , p[b]))); // cout<<j<<' '<<area<<endl;
- if(compare(mn , area) == 1){
- mn=area;
- c=j;
- }
- }
- cout<<a<<' '<<b<<' '<<c<<endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement