【容斥(其实并不是)】【USACO】数三角形

来源:互联网 发布:怎样申请淘宝卡 编辑:程序博客网 时间:2024/05/04 07:15

543. [USACO Open10]数三角形

★★☆   输入文件:tricount.in   输出文件:tricount.out   简单对比时间限制:1 s   内存限制:128 MB

在一只大灰狼偷偷潜入Farmer Don的牛群被群牛发现后,贝西现在不得不履行着她站岗的职责。

从她的守卫塔向下瞭望简直就是一件烦透了的事情。她决定做一些开发智力的小练习,防止她睡着了。

想象牧场是一个X,Y平面的网格。她将N只奶牛标记为1…N (1 <= N <= 100,000),每只奶牛的坐标为X_i,Y_i (-100,000 <= X_i <= 100,000;-100,000 <= Y_i <= 100,000; 1 <= i <=N)。然后她脑海里想象着所有可能由奶牛构成的三角形。如果一个三角形完全包含了原点(0,0),那么她称这个三角形为“黄金三角形”。原点不会落在任何一对奶牛的连线上。另外,不会有奶牛在原点。
给出奶牛的坐标,计算出有多少个“黄金三角形”。

顺便解释一下样例,考虑五只牛,坐标分别为(-5,0), (0,2), (11,2), (-11,-6), (11,-5)。
下图是由贝西视角所绘出的图示。
…………|…………
…………………..
…………|…………
——-*—-+————
…………|…………
…………|…………
…………|…………
…………|…………
…………|……….*.
.*……….|…………
…………|…………
所有十个三角形如图下所示:

通过观察,其中有5个构成了“黄金三角形”

輸入格式:
* 第一行:一个整数: N
* 第2到第N+1行: 每行两个整数X_i,Y_i,表示每只牛的坐标

樣例輸入 (文件 tricount.in):
5
-5 0
0 2
11 2
-11 -6
11 -5

輸出格式:

  • 第一行: 一行包括一个整数,表示“黄金三角形的数量”

樣例輸出 (文件 tricount.out):

5

题解:

懒得写了。。cstdio大神写得非常好。
详见——>这里写链接内容
简单说就是对极角排序,然后扫一遍,判断不符合的三角形,然后算一下就好了。

Code:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define LL long longstruct A{    LL x,y;    double z;}a[200100];int in(){    int x=0; char ch=getchar(); bool f=true;    while (ch<'0' || ch>'9'){        if (ch=='-') f=false;        ch=getchar();    }    while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();    if (!f) x=-x;    return x;}bool cmp(A x,A y){    return x.z<y.z;}LL chaji(A x,A y){    return x.x*y.y-y.x*x.y;}int main(){    int n=in();    for (int i=1; i<=n; i++){        a[i].x=(LL)in(),a[i].y=(LL)in();        a[i].z=atan2((double)a[i].y,(double)a[i].x);    }    sort(a+1,a+n+1,cmp);    for (int i=1; i<=n; i++) a[i+n]=(A)a[i];    LL ans=(LL)n*(n-1)*(n-2)/6;    int i,j;    for (i=1,j=1; i<=n; i++){        for (; j<i+n && chaji(a[i],a[j])>=0; j++);        LL k=(LL)j-i-1;        ans-=k*(k-1)/2;    }    printf("%lld\n",ans);    return 0;}
0 0
原创粉丝点击