给你500个红点和蓝点,让你找多少点红点构成的三角形里没有蓝点。
巧妙啊!我们考虑一个很远位置的点,不妨设这个为O,然后n^2枚举红点,考虑Oij里面蓝点的个数,
然后 对于 ijk这个三角形,我们可以求一 OIJ+OJK+OKI,看是否符合条件。
1 #include <bits/stdc++.h> 2 #define p OvO 3 using namespace std; 4 typedef long long ll; 5 int sign(ll k){ 6 if (k>0) return 1; else if (k<0) return -1; return 0; 7 } 8 struct point { 9 ll x,y; 10 point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};} 11 }; 12 ll cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;} 13 int clockwise(point k1,point k2,point k3){// k1 k2 k3 逆时针 1 顺时针 -1 否则 0 14 return sign(cross(k2-k1,k3-k1)); 15 } 16 int n,m,dp[505][505];point a[505],b[505]; 17 int main(){ 18 scanf("%d%d",&n,&m); 19 for(int i=1;i<=n;i++){ 20 scanf("%lld%lld",&a[i].x,&a[i].y); 21 } 22 for(int i=1;i<=m;i++){ 23 scanf("%lld%lld",&b[i].x,&b[i].y); 24 } 25 a[0] = {1135813210,1135813210}; 26 for(int i=1;i<=n;i++){ 27 for(int j=1;j<=n;j++){ 28 if(cross(a[i]-a[0],a[j]-a[0])<=0)continue; 29 for(int k=1;k<=m;k++){ 30 if(clockwise(a[0],a[i],b[k])>0&&clockwise(a[i],a[j],b[k])>0&&clockwise(a[0],a[j],b[k])<0) 31 dp[i][j]++; 32 } 33 dp[j][i]=-dp[i][j]; 34 } 35 } 36 int ans = 0; 37 for(int i=1;i<=n;i++){ 38 for(int j=i+1;j<=n;j++){ 39 for(int k=j+1;k<=n;k++){ 40 if(dp[i][j]+dp[j][k]+dp[k][i]==0) 41 ans++; 42 } 43 } 44 } 45 printf("%d ",ans); 46 }