本题是向量叉积的应用,应用向量叉积可以判断一个点是否在三角形内部。
向量积 axb =|a|*|b|*sin<a,b>
当b在a的逆时针方向,向量积是正数,反之,是负数。
由图可知三角形内部的点都在三角形边的同一侧。
可以结合此性质解决本题。
绿色和红色区域可以根据三角形行走的方向相消为0
#include<iostream> #include<cstring> #include<cmath> #include<assert.h> #include<stdio.h> using namespace std; typedef __int64 lld; const int INF=1000000000; struct P { lld x,y; P(){}; P(lld x,lld y):x(x),y(y){}; P operator -(const P & b)const { P tmp(x-b.x,y-b.y); return tmp; } }; lld cross(P a,P b) { return a.x*b.y-a.y*b.x; } P red[505],blue[505]; int cnt[505][505]; int main() { int i,j,k; int N,M; lld x,y; memset(cnt,0,sizeof(cnt)); freopen("D:\codeforces\D. Triangles\data\20.in","r",stdin); freopen("D:\codeforces\D. Triangles\data\20.out","w",stdout); cin>>N>>M; assert(N>=0&&N<=500); assert(M>=0&&M<=500); for(i=0;i<N;i++) { cin>>x>>y; assert(x>=-INF&&x<=INF); assert(y>=-INF&&y<=INF); red[i]=P(x,y); } for(i=0;i<M;i++) { cin>>x>>y; assert(x>=-INF&&x<=INF); assert(y>=-INF&&y<=INF); blue[i]=P(x,y); } for(i=0;i<N;i++) { for(j=0;j<N;j++) { if(i==j||red[i].x>red[j].x)continue; for(k=0;k<M;k++) { if(blue[k].x>=red[i].x&&blue[k].x<red[j].x&&cross(blue[k]-red[i],red[j]-red[i])>0) cnt[i][j]++; } cnt[j][i]=-cnt[i][j]; } } int ans=0; for(i=0;i<N;i++) { for(j=i+1;j<N;j++) for(k=j+1;k<N;k++) { if(cnt[i][j]+cnt[j][k]+cnt[k][i]==0) ans++; } } cout<<ans<<endl; return 0; }