hdu-5784 How Many Triangles(计算几何+极角排序)

题目链接:

How Many Triangles

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 570    Accepted Submission(s): 183

Problem Description

Alice has n points in two-dimensional plane. She wants to know how many different acute triangles they can form. Two triangles are considered different if they differ in at least one point.

Input

The input contains multiple test cases.
For each test case, begin with an integer n,
next n lines each contains two integers xi and yi.
3≤n≤2000
0≤xi,yi≤1e9
Any two points will not coincide.

Output

For each test case output a line contains an integer.

Sample Input

3

1 1

2 2

2 3

3

1 1

2 3

3 2

4

1 1

3 1

4 1

2 3

Sample Output

0

1

2

题意:

问有多少个锐角三角形,跟以前的求钝角和直角三角形一样,要用极角排序,不过这道题的点有共线的,所以要结合一下三角形的知识,其实就是锐角三角形三个锐角,直角和钝角三角形有两个锐角,求出锐角的个数,钝角和直角的个数,然后锐角个数减去两倍的直角钝角个数,再除3就是答案了,极角排序的问题就是精度问题了;精度ep开的小一点啦就能过啦;

思路:

哎哟,上边一不小心就说了;

AC代码;

/************************************************
┆  ┏┓   ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃       ┃ ┆
┆┃   ━   ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃       ┃ ┆
┆┃   ┻   ┃ ┆
┆┗━┓    ┏━┛ ┆
┆  ┃    ┃  ┆      
┆  ┃    ┗━━━┓ ┆
┆  ┃  AC代马   ┣┓┆
┆  ┃           ┏┛┆
┆  ┗┓┓┏━┳┓┏┛ ┆
┆   ┃┫┫ ┃┫┫ ┆
┆   ┗┻┛ ┗┻┛ ┆
************************************************ */ 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>

using namespace std;

#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));

typedef  long long LL;

template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar());
    for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + ‘0‘);
    putchar(‘\n‘);
}

const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=5e4+10;
const int maxn=2e3+14;
const double eps=1e-12;

double temp[2*maxn];
int n;
struct node
{
    double x,y;
}po[maxn];

int main()
{
        while(scanf("%d",&n)!=EOF)
        {
            For(i,1,n)
            {
                scanf("%lf%lf",&po[i].x,&po[i].y);
            }
            LL ans1=0,ans2=0;
            For(i,1,n)
            {
                int cnt=0;
                For(j,1,n)
                {
                    if(i==j)continue;
                    temp[++cnt]=atan2(po[j].y-po[i].y,po[j].x-po[i].x);
                    if(temp[cnt]<0)temp[cnt]+=2*PI;
                }
                sort(temp+1,temp+cnt+1);
                For(j,1,cnt)
                {
                    temp[j+cnt]=temp[j]+2*PI;
                }
                int l=1,r=1,le=1;
                For(j,1,cnt)
                {
                    while(temp[r]-temp[j]<PI&&r<=2*cnt)r++;
                    while(temp[l]-temp[j]<0.5*PI&&l<=2*cnt)l++;
                    while(temp[le]-temp[j]<=eps&&le<=2*cnt)le++;
                    ans1=ans1+r-l;
                    ans2=ans2+l-le;
                }
            }
            cout<<(ans2-2*ans1)/3<<"\n";
        }
        return 0;
}

  

时间: 2024-10-20 10:02:44

hdu-5784 How Many Triangles(计算几何+极角排序)的相关文章

多校 #5 hdu 5784 How Many Triangles

http://acm.hdu.edu.cn/showproblem.php?pid=5784 给定平面上互不相同的n个点,求所有锐角三角形的个数.3<=n<=2000 锐角三角形因为要三个角都是锐角,所以限制条件多.即使枚举一个点,另外两条边用极角排序,也只能维护一个锐角,剩下的两个角难于统计. 但是,如果换一种思路,统计所有直角.钝角以及三点共线的个数 ,问题就简单多了.因为因为只有一个直角或钝角或平角,只需依次对每个点,统计以它为哪一个特殊角的直角.钝角.平角三角形有多少即可. 具体做法是

[POJ2007]Scrambled Polygon(计算几何 极角排序)

题目链接:http://poj.org/problem?id=2007 题意:给出凸包和起点,逆序输出. 极角排序可以用反三角函数求出角度,按照角度排序.也可以用叉乘来做.注意题目说给定第一个数据是0,0,这是凸包的起点,数据中有在x轴负半轴的数据,所以排序的时候0,0要跳过.只排1~n-1个坐标. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstri

HDU 5784 How Many Triangles

给你一堆点,找锐角三角形. TWO POINTER 思想. 统计出所有锐角和直=钝角的数目. 做法是这样的:对每个点对所有点极角排序,然后TWO POINTER计算每一个锐角(一个边上有好几个点也会被统计好几次),直角钝角.然后ans=(锐角个数-直角钝角个数*2)/3;因为每一个角度可能也只可能出现在一个三角形中. 但是一上来没弄懂,所以队友想了一个思路也能过,先统计直角和钝角的个数.然后C(n,3)统计所有情况,不能构成三角形的是三点共线的情况,所以n^2logn统计三点共线(TWO POI

HDU 3532 Max Angle(计算几何——极角排序)

传送门 Max Angle Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 704    Accepted Submission(s): 253 Problem Description Given many points in a plane, two players are playing an interesting game. Pl

POJ Transmitters(计算几何 极角排序啊)

题目链接:http://poj.org/problem?id=1106 Description In a wireless network with multiple transmitters sending on the same frequencies, it is often a requirement that signals don't overlap, or at least that they don't conflict. One way of accomplishing thi

【计算几何+极角排序+爆ll】E. Convex

https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/E [题意] 给定n个点的坐标,可以选择其中的四个点构造凸四边形,问最多能构造多少个凸四边形? [思路] 凸四边形的个数等于C(n,4)-凹四边形的个数. 凹四边形的特点是有一个顶点被另外三个顶点围成的三角形包了起来. 所以现在的问题就是找凹四边形. 我们可以枚举每个点,作为被三角形包围的中心点o.怎么找这样包围中心点的三角形? 这样的三角形一定是在存在一条经过中心点的直线,三角

【计算几何】【极角排序】【二分】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem J. Triangles

平面上给你n(不超过2000)个点,问你能构成多少个面积在[A,B]之间的Rt三角形. 枚举每个点作为直角顶点,对其他点极角排序,同方向的按长度排序,然后依次枚举每个向量,与其对应的另一条直角边是单调的,可以用一个pointer做出来,然后可以得出那些同方向的向量的区间(这个代码好像有点问题,可能会退化,最好确定了一个LL之后,对一个方向的不要重复算RR.这里如果也改成二分就比较好,复杂度不会退化).然后通过二分可以得到A使得面积在[A,B]间的有哪些(其实这个因为也是单调的,好像也没必要二分,

HDU 5784 (计算几何)

Problem How Many Triangles (HDU 5784) 题目大意 给定平面上的n个点(n<2000),询问可以组成多少个锐角三角形. 解题分析 直接统计锐角三角形较困难,考虑问题的反面,统计直角三角形.钝角三角形.平角三角形(暂时这么叫吧QAQ). 首先枚举三角形的一个端点A,对其他点进行象限为第一关键字,极角为第二关键字排序. 然后使用三个指针,进行O(n)的扫描. 具体做法为用 i 指针指向三角形的第二个端点B.我们可以假想通过平移和旋转,把A点置于平面直角坐标系的原点,

【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

acm.hdu.edu.cn/showproblem.php?pid=6127 [题意] 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权 这n个点两两可以连乘一条线段,定义每条线段的权值为线段两端点点权的乘积 现在要过原点作一条直线,要求这条直线不经过任意一个给定的点 在所有n个点两两连成的线段中,计算与这条直线有交点的线段的权值和 最大化这个权值和并输出 题目保证,给定的n个点不重合且任意两个点的连线不经过原点 [思路] 一条经过原点的直线把n个点分成两个半平面A,B 假设A中的点权