Not write code. . Forget the scanning line plus s = max (i, s) up
and did not transfer out. . . . .
Retired more than two months, the feeling turned into a mouth (((
I think the idea is very good, which is also the general line by scanning it.
My idea:
Consider "castle" this thing,
we found that if a triangle + the middle of a point, then as long as we then just add a point on the ok
is the "triangle containing a point." * (N-4)
Consider computing a number of triangular points are contained,
so hard. Let us count as one point is not how many triangles contain simple.
For a scan line, as long as we select two points on one side of it, then this is a triangle that does not contain the center point,
then we (n-1,3) by subtracting the triangle does not contain C can be obtained comprising a triangle.
Then included in the triangle * (n-4)
Test sample, Hey, just are twice as large, so weDivided by two direct submission
Draw a map,
found that indeed is the case, no matter how put four points, intermediate points will be counted in two triangles, so the contribution divided by 2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct point{
ll x,y,id;
point operator +(const point & k1)const {return (point){k1.x+x,k1.y+y};}
point operator -(const point & k1)const {return (point){x-k1.x,y-k1.y};}
inline int getP()const {return y>0||(y==0&&x<0);}
};
inline ll cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
inline ll dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
inline int compareangle(point k1,point k2){
return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&cross(k1,k2)>0);
}
ll n;
point p[2525];
ll slove(int id){//无三点共线
//找不包含 id 的三角形
vector<point> v;
for(int i=1;i<=n;i++)if(i!=id)v.push_back(p[i]-p[id]);
sort(v.begin(),v.end(),compareangle);
int m = v.size();
// for(auto x:v)cout<<x.x<<' '<<x.y<<endl;
for(int i=0;i<m;i++)v.push_back(v[i]);
ll res = 0;
int s=0;
for(int i=0;i<m;i++){
point _180 = {-v[i].x,-v[i].y};
s=max(i,s);
while (s<i+m-1&&(cross(v[s+1],_180)>0&&cross(v[s+1],v[i])<0))s++;
//s<180
int cnt = s-i;
res += 1ll*cnt*(cnt-1)/2;
}
ll sum = 1ll*(n-1)*(n-2)*(n-3)/6;
sum-=res;//被多少个三角形包含
return sum*(n-4);
}
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&p[i].x,&p[i].y);
}
ll ans = 0;
for(int i=1;i<=n;i++){
// cout<<slove(i)<<endl;
ans+=slove(i);
}
cout<<ans/2<<endl;
}