codeforces 13 D

给你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 }
View Code
原文地址:https://www.cnblogs.com/MXang/p/10749965.html