http://acm.hdu.edu.cn/showproblem.php?pid=5784
题意:n个点,找多少个锐角三角形数目
思路:极角排序+two pointers
当前选择的点集要倍增一倍,点集过大时,极角排序后,后面的点有可能和前面的点形成钝角
ans=总的三角形数目 - 三点共线的情况-直角和钝角
1 // #pragma comment(linker, "/STACK:102c000000,102c000000") 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <sstream> 6 #include <string> 7 #include <algorithm> 8 #include <list> 9 #include <map> 10 #include <vector> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <cstdlib> 15 // #include <conio.h> 16 using namespace std; 17 #define clc(a,b) memset(a,b,sizeof(a)) 18 #define inf 0x3f3f3f3f 19 #define lson l,mid,rt<<1 20 // #define rson mid+1,r,rt<<1|1 21 const int N = 2010; 22 const int M = 1e6+10; 23 const int MOD = 1e9+7; 24 #define LL long long 25 #define LB long double 26 // #define mi() (l+r)>>1 27 double const pi = acos(-1); 28 const double eps = 1e-8; 29 void fre(){freopen("in.txt","r",stdin);} 30 inline int read(){int x=0,f=1;char ch=getchar();while(ch>‘9‘||ch<‘0‘) {if(ch==‘-‘) f=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘;ch=getchar();}return x*f;} 31 32 struct Point{ 33 LL x,y; 34 Point(){} 35 Point(LL _x,LL _y):x(_x),y(_y){} 36 Point operator + (const Point &t)const{ 37 return Point(x+t.x,y+t.y); 38 } 39 Point operator - (const Point &t)const{ 40 return Point(x-t.x,y-t.y); 41 } 42 LL operator * (const Point &t)const{ 43 return x*t.y-y*t.x; 44 } 45 LL operator ^ (const Point &t)const{ 46 return x*t.x+y*t.y; 47 } 48 bool operator < (const Point &b)const{ 49 if (y * 1LL * b.y <= 0) { 50 if (y > 0 || b.y > 0) return y < b.y; 51 if (y == 0 && b.y == 0) return x < b.x; 52 } 53 return (*this)*b > 0; 54 } 55 }p[N],v[N<<1]; 56 57 int main(){ 58 int n; 59 while(~scanf("%d",&n)){ 60 for(int i=0;i<n;i++) scanf("%I64d%I64d",&p[i].x,&p[i].y); 61 LL ans=1LL*n*(n-1)*(n-2)/6,tem=0; 62 for(int k=0;k<n;k++){ 63 int cnt=0; 64 for(int i=0;i<n;i++){ 65 if(k==i)continue; 66 v[cnt++]=p[i]-p[k]; 67 } 68 sort(v,v+cnt); 69 for(int i=0;i<cnt;i++) v[i+cnt]=v[i]; 70 int cxt=0; 71 for(int i=1;i<cnt;i++){ 72 if(v[i-1]*v[i]==0&&(v[i-1]^v[i])>0) cxt++; 73 else cxt=0; 74 tem+=cxt; 75 } 76 for(int i=0,p1=0,p2=0;i<cnt;i++){ 77 while(p1<=i||(p1<i+cnt&&v[p1]*v[i]<0&&(v[p1]^v[i])>0)) p1++; 78 while(p2<=i||(p2<i+cnt&&v[p2]*v[i]<0)) p2++; 79 ans-=p2-p1; 80 } 81 } 82 printf("%I64d\n",ans-tem/2); 83 } 84 return 0; 85 }
时间: 2024-10-23 09:19:50