cf#308-D - Vanya and Triangles-求平面点集中三角形个数-枚举-n^2logn

来源:互联网 发布:美国最新非农数据 编辑:程序博客网 时间:2024/05/16 19:04

http://codeforces.com/contest/552/problem/D


给n,n个点,求构成的面积非零的三角形个数。。


共c(n,3)种,要除去三点共线的即可咯


枚举点i ,对所有(j>i)的点 ,求一遍斜率,最后  与点i构成斜率为K的点数有x个,那么便有C(x,2)个共线三角形咯。  全部累加起来最后 被c(n,3)减去就是答案了咯

统计斜率部分用map比较方便咯

【注意爆int】【注意double精度问题 】

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;const double pi=acos(-1.0);double eps=0.000001; __int64 min(__int64 a,__int64 b){return a<b?a:b;} __int64 max(__int64 a,__int64 b){return a>b?a:b;} struct POINT { int x; int y; POINT(double a=0, double b=0) { x=a; y=b;} //constructor double jijiao;};POINT p[2005];__int64 gcd(__int64 a,__int64 b){if (!b)return a;else return gcd(b,a%b);} double get(__int64 i,__int64 j) {__int64 y=p[i].y-p[j].y;__int64 x=p[i].x-p[j].x; if (!x)return 100000;__int64 gd=gcd(x,y);x/=gd;y/=gd; return (y*1.0/x); } map <double,__int64 >sb; map <double,__int64 >::iterator it;;int main() {__int64 n;scanf("%I64d",&n);__int64 i,j; for (i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);   __int64 ans=0;for (i=1;i<=n;i++){sb.clear();for(j=i+1;j<=n;j++){  double k=get(i,j);sb[k]++;}for (it=sb.begin();it!=sb.end();it++){ if (it->second>=2)ans+= (it->second)*(it->second-1)/2  ;} }printf("%I64d\n",n*(n-1)*(n-2)/6-ans);return 0;}


0 0