1. 程式人生 > >Hdu 5784 How Many Triangles(極角排序+尺取法)

Hdu 5784 How Many Triangles(極角排序+尺取法)

思路:

1.銳角三角形總銳角個數=總銳角數-非銳角三角形提供銳角數。則銳角三角形個數=總銳角數/3(即(銳角數-2*(直角+鈍角數))/3,每鈍角和直角三角形提供兩銳角)。

2.列舉每個點p[i],以p[i]為原點,求其他n-1個點與原點組成的向量,按極角(小於0時加2*PI)遞增排序。設定三個指標l、r、equ,分別代表第一個直角、第一個平角、第一個非0角的位置。列舉n-1個向量j,由於極角遞增,兩向量角度即為極角l-極角j,l、r、equ遞增則形成的角度也遞增(相當於尺取法)。則以點p[i]為頂點的銳角個數為l-equ(所有小於90度的角減去0度的角),鈍角個數為r-l(所有小於180度的角減去小於等於90度的角)。

3.當指標l、r、equ旋轉一週時(l、r、equ下標超過n-1,但此時所有角度尚未列舉完畢),為了便於求角度(即最後一部分向量與起始部分向量所成角度),列舉之前將所有極角加2*PI複製一遍。

#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug
using namespace std;

const double eps=1e-11;
const double PI=acos(-1.0);
const int maxn=4000+50;

int n;

struct Point
{
    double x,y;
    Point() {}
    Point(double x,double y):x(x),y(y) {}
    void read()
    {
        scanf("%lf%lf",&x,&y);
    }
};

typedef Point Vector;

Vector operator - (Vector A,Vector B)
{
    return Vector(A.x-B.x,A.y-B.y);
}

int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}

int cnt;
Point p[maxn];
double a[maxn];

int main()
{
#ifdef debu
    freopen("in.txt","r",stdin);
#endif // debug
    while(scanf("%d",&n)!=EOF)
    {
        int acute=0,notacute=0;
        for(int i=1; i<=n; i++) p[i].read();
        for(int i=1; i<=n; i++)
        {
            cnt=0;
            for(int j=1; j<=n; j++)
            {
                if(i==j)continue;
                Vector tmp=p[j]-p[i];
                double ang=atan2(tmp.y,tmp.x);
                if(ang<0) ang+=2*PI;
                a[++cnt]=ang;
            }

            sort(a+1,a+cnt+1);

            for(int j=1;j<=cnt;j++) a[cnt+j]=a[j]+2*PI;

            int l=1,r=1,equ=1;

            for(int j=1; j<=cnt; j++)
            {
                while(l<=2*cnt&&dcmp(a[l]-a[j]-PI/2)<0) l++;
                while(r<=2*cnt&&dcmp(a[r]-a[j]-PI)<0) r++;
                while(equ<=2*cnt&&dcmp(a[equ]-a[j])==0) equ++;


                acute+=l-equ;
                notacute+=r-l;
            }
        }

        printf("%d\n",(acute-2*notacute)/3);
    }
    return 0;
}


相關推薦

Hdu 5784 How Many Triangles排序+取法

思路: 1.銳角三角形總銳角個數=總銳角數-非銳角三角形提供銳角數。則銳角三角形個數=總銳角數/3(即(銳角數-2*(直角+鈍角數))/3,每鈍角和直角三角形提供兩銳角)。 2.列舉每個點p[i],以p[i]為原點,求其他n-1個點與原點組成的向量,按極角(小於0時加2*

hdu 5784 How Many Triangles 排序計算銳角直角鈍角

題目大意:給你n個點,計算有多少個銳角三角形。 銳角三角形個數=(圖中銳角個數-鈍直角個數*2)/3 轉化為計算圖中有幾個鈍直角,銳角。列舉角的頂點,然後再列舉該頂點引出的邊,可以用向量表示。對這些向量進行極角排序,列舉起始邊,用尺取的方法,算得與該邊成銳角,鈍直角的邊的條

HDU 5784 How Many Triangles(排序)

題意很簡單,平面上給你n個點,求銳角三角形的個數,點沒有重復 首先就是隨便選三個點C(n,3),可能構成銳角,直角,鈍角,並且直角鈍角都不會重復計算 所以銳角的個數就是C(n,3)−直角−鈍角−三點共線 這裡用點乘和叉乘來求解直角鈍角還有三點共線的問題

How Many Triangles (排序 + 取法)

  題意:二維平面與有很多個點,然後求構成銳角三角形的個數。   思路:對於每一個三角形我們知道存在至少2個銳角,只要有一個鈍角就不行了,所以我們的想法就是列舉所有夾角的狀態,然後得知情況,確定用總個數減去-成線或者成鈍角的數量/2(除以2是因為計算過程中重複了)。那麼應該如何列舉?我們列舉夾角的頂點然後就

POJ 2566 Bound Found字首和排序 + 取法

題意:對一個長度為n的數列,做k次查詢,每次查詢一個數t,求原數列中的一個子區間[l, r],使得該子區間的和的絕對值最接近t。 思路:在原數列開頭新增一個0,處理好現數列a[N]的字首和pre[N]。則原問題轉化為在字首陣列中求2個數pre[i],pre

5784 How Many Triangles 排序

題意:給出n個不重合的點,問能形成多少個不同的銳角三角形。 思路:統計出所有的銳角,直角,鈍角的數量,假設分別為A,B,C,由於一個鈍角或者直角三角形中也包含兩個銳角,因此答案為(A - 2 * (

HDU 1978 How many ways記憶化搜尋

   How many ways   Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other

HDU 1213 How Many Tables並查集

傳送門 題目翻譯出來就是:今天是Ignatius的生日,他邀請了許多朋友。現在是吃晚飯的時間,Ignatius想知道他至少需要準備多少桌。必須注意的是,並非所有的朋友都相互認識對方,有的人不願意和陌生人坐在一桌。針對此問題的一個重要的規則是,如果我告訴你A知道B,B知道C,這意味著,A和C認識對

hdu 1213 How Many Tables簡單並查集

題意就是 給出n對關係,假如A和B認識,B和C認識,那麼A和B認識。現在互相認識的人可以在一桌吃飯,不互相認識的人可以一桌吃飯,問需要多少張桌子 #pragma GCC optimize(2) #include<stdio.h> #include<a

POJ 1696 Space Ant 排序

img NPU values red 極角排序 {} num clock cts 題目: Description The most exciting space discovery occurred at the end of the 20th century. In

POJ 1696 Space Ant排序【計算幾何】

Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2489 Accepted: 1567 Description The most exci

【POJ 3004】Subway planning排序+貪心

Time Limit: 2000MSMemory Limit: 65536KTotal Submissions: 1384Accepted: 375 Description The government in a foreign country is looking into the possibility

HDU 1285 確定比賽名次拓撲排序基礎題

個數 排名 有向無環圖 沒有 left php 輸出 編號 整數 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 題目: 有N個比賽隊(1<=N<=500),編號依次為1,2,3,。。。。,N進行比賽,

HDU 3342 Legal or Not拓撲排序判環

題解 eas n-1 all day sim contain target there 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3342 題目: Problem Description ACM-DIY is a l

HDU 3038 How Many Answers Are Wrong帶權並查集

define pro tor memset set sizeof fin printf class 題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1272 題目大意:有n條信息,每條信息都給出區間l到r的值,如果

HDU-1796 How many integers can you find容斥原理

                            How many integers can you find      

HDU 5137 How Many Maos Does the Guanxi Worth最短路+列舉

題解: 首先先跑一遍最短路,用pre陣列記錄最短路路徑,列舉路徑上的所有點(不包括 1 和 n),標記這些點再來跑最短路記錄其中最大的最短路。 #include <algorithm> #include <iostream> #include

HDU 3038 How Many Answers Are Wrong 帶權並查集

Problem Description TT and FF are ... friends. Uh... very very good friends -________-b FF is a bad boy, he is always wooing TT to play t

hdu 2609 How many最小表示法模板+set判重

題目連結: 解題思路: 題目大意: 有n個有01組成的字串,每個字串都代表一個項鍊,那麼該字串就是一個環狀的結構,求可以經過迴圈旋轉,最後不同的串有多少個。。 演算法思想: 將每個字串轉換成最小串,

HDU 2609 How many 字串最小字典序+set去重

題目連結 Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell me  How many kinds of necklaces total have.(if t