これは、必要な数学的知識である(DP?\)\
アイディア
まず、どの点が三角形の内側にあるかどうかを決定する-私達は仮定する(\ \ ABC \ bigtriangleup)ならびに点を決定する\(Pを\) 、もし\(P \)で\(ABC \)内部、その後縁\(AB \)、点\(P \)と点\(C \)側に\(AB \)同側、エッジ上の\(BC \) 、点\(P \)と点\(\)同側のBC、同様に、一方\(ACが\)真です。私たちは、クロス積、外積を達成するためにこのアイデアを使用することができます(> 0 \)\、クロス製品の同じ側にある\は、(<0 \)異なる側面です。
我々は、原点設定(\ O)\を、(座標入力範囲外であるべきである)各赤い点2点を探して、2点を求めて(\ O)\青色のドット数の三角形\(DP [I] [J ] \) に保存。
私たちは、赤い点がマーク3つのドットの三角形を選択したことを前提としてい\(ABC \)を、その後、
\(\ Bigtriangleup ABC \テキスト{青色のドット数} = \ OAB bigtriangleup + \ bigtriangleup OBC - \ bigtriangleup OAC \)
コード
開くことを忘れないでください\(ロングロング〜\)行くだろう、あるいはサンプルを
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<queue>
#define int long long
#define maxn 505
#define inf 2147483647
#define mod 998244353
#define eps 1e-6
#define pi acos(-1.0)
#define de(x) ((x)*(x))
using namespace std;
inline int read(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
return x*f;
}
int dp[maxn][maxn];
struct Node{
int x, y;
Node() {}
Node(int xi, int yi):x(xi), y(yi){}
Node operator - (const Node &N) const{return Node(x-N.x, y-N.y);}
inline int operator * (const Node &N) const{return x*N.y-y*N.x;}
}red[maxn],blue[maxn];
signed main(){
int n=read(),m=read();
for(int i=0;i<n;i++) red[i].x=read(),red[i].y=read();
for(int i=0;i<m;i++) blue[i].x=read(),blue[i].y=read();
Node a=Node(-1000000001,-1000000001);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if((red[i]-a)*(red[j]-a)<=0) continue;
for(int k=0;k<m;k++){
if((red[i]-a)*(blue[k]-a)>0&&(red[j]-red[i])*(blue[k]-red[i])>0&&(a-red[j])*(blue[k]-red[j])>0)
dp[i][j]++;
}
dp[j][i]=-dp[i][j];
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
for(int k=j+1;k<n;k++)
ans+=(dp[i][j]+dp[j][k]+dp[k][i]==0);
printf("%d",ans);
return 0;
}