正题
纪中题目链接:https://jzoj.net/senior/#main/show/3493
题目大意
给n点,求有多少个三角形。
##解题思路
我们考虑在n个点中选取3个点的方案数,Cn3C_n^3Cn3。然后不能组成三角形的情况只有3点共线。利用容斥原理我们可以用方案数减去不合法的方案数。现在问题变为了n个点中有多个个3点共线。
我们枚举一个点,然后求出他和其他点的斜率,将斜率排序再计算有多少个方案选取两个斜率相同的点就是答案。
(注意判断tan90°的情况)
误差听说要在10−910^{-9}10−9以内
时间复杂度:O(n2logn)O(n^2log\ n)O(n2log n)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 3010
#define inf 2147483647
#define eps 1e-9
using namespace std;
int n,x[N],y[N];
double p[N];
long long ans;
int main()
{//freopen("triangle.in","r",stdin);//freopen("triangle.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);ans+=(long long)(n-2)*(n-1)*n/6;//总方案数for(int i=3;i<=n;i++){int num=0;for(int j=1;j<i;j++){double a1=x[i]-x[j],b1=y[i]-y[j];if(!b1) num++;//tan90°p[j]=a1/b1;//计算斜率}sort(p+1,p+i);p[i]=2147483647;int k=1;for(int j=1;j<i;j++)if(p[j+1]-p[j]<eps) k++;//斜率相等else{ans-=k*(k-1)/2;//去除不合法方案k=1;}ans-=num*(num-1)/2;//tan90°}printf("%lld",ans);
}