zoukankan      html  css  js  c++  java
  • 极角排序+求锐角三角形个数——uva12123

    这个版本还不能处理三点共线的情况(处理起来其实比较麻烦)

    可以用atan2来排序(较为简单,但是精度误差大),也可以用叉积排序(比较优秀)

    atan2

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    typedef long long LL;
    const int maxn = 1250;
    const double pi = acos(-1.0);
    const double eps = 1e-10;
     
    struct point{
        double x,y;
    }p[maxn];
    double s[maxn*2];
     
    int main()
    {
        //freopen("input.txt" , "r" , stdin);
        int N , cas = 1;
        while(scanf("%d" ,&N)!=EOF && N){
     
            for(int i=0;i<N;i++)
                scanf("%lf%lf" , &p[i].x , &p[i].y);
            LL obtuse = 0;
            for(int i=0;i<N;i++){
                if(i) swap(p[i] , p[0]);
                for(int k=1;k<N;k++) s[k] = atan2(p[k].y-p[0].y , p[k].x-p[0].x);
                sort(s+1 , s+N);
                for(int k=1;k<N;k++) s[k+N-1] = s[k] + 2*pi;
     
                int k=1 , e1=1 , e2=1;
                for(; k<N; k++){
                    while(s[e1] - s[k] - 0.5*pi < -eps) e1++;
                    while(s[e2] - s[k] <= pi) e2++;
                    obtuse += e2 - e1;
                }
            }
            LL ans = N*(N-1)*(N-2)/6 - obtuse;
            printf("Scenario %d:
    " , cas++);
            printf("There are %lld sites for making valid tracks
    " , ans);
        }
        return 0;
    }

    叉积

    /*
    极角排序:定义极角大小顺序是3412象限 
    求锐角三角形个数/总面积(可能三点共线)
        总三角形-直角三角形-钝角三角形=C(n,3)-直角个数-钝角个数
        以每个点为源点,级角排序,然后双指针扫一次求直角钝角个数
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 4005
    typedef double db;
    const db eps=1e-6;
    const db pi=acos(-1);
    int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;}
    int cmp(db k1,db k2){return sign(k1-k2);}
    
    struct point{
        db x,y;
        point(){}
        point(db x,db y):x(x),y(y){}
        point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
        point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
        point operator * (db k1) const{return (point){x*k1,y*k1};}
        point operator / (db k1) const{return (point){x/k1,y/k1};}
        int getP() const{return sign(y)==1||(sign(y)==0&&sign(x)>=0);} 
    };
    db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
    db rad(point k1,point k2){return atan2(cross(k1,k2),dot(k1,k2));}
    int comp(point k1,point k2){
        if(k1.getP()==k2.getP())return sign(cross(k1,k2))>0;
        return k1.getP()<k2.getP();
    }
    
    int n,ans;
    point pp[N],p[N],O;
    
    int main(){
        int tt=0;
        while(cin>>n && n){
            ++tt;
            for(int i=1;i<=n;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            ans=n*(n-1)*(n-2)/6;
            
            long long sum=0;
            for(int i=1;i<=n;i++){
                O=p[i];
                int tot=0;
                for(int j=1;j<=n;j++)
                    if(j!=i)pp[++tot]=p[j]-O;
                sort(pp+1,pp+1+tot,comp);
                for(int j=1;j<=tot;j++)
                    pp[j+tot]=pp[j];
                
                int p1=1,p2=1;
                for(int j=1;j<=tot;j++){
                    //p1的夹角[0,pi/2) 
                    while(p1+1<j+tot && sign(cross(pp[j],pp[p1+1]))>=0 && sign(dot(pp[j],pp[p1+1]))>0)
                        p1++;
                    //p2的夹角[0,pi] 
                    while(p2+1<j+tot && sign(cross(pp[j],pp[p2+1]))>=0)
                        p2++;
                    sum+=p2-p1;
                }
            }
            printf("Scenario %d:
    ",tt);
            printf("There are %d sites for making valid tracks
    ",ans-sum);
        }
    }
    /*
    6
    26 23
    51 94
    103 110
    164 107
    116 67
    73 16
    */
  • 相关阅读:
    北京礼品在线盛大发布
    医生专用手机(智能、导航、名片扫描、医生掌上电子助手)
    医生专用手机/PDA
    DEDE 栏目内容 {dede:field.content/} 输入值不保存解决方法
    礼至上礼品策划中心
    ASP.NET WAP开发
    国内唯一具有智能礼品推荐系统
    招聘发帖兼职人员帖酬高达0.5元/条http://li010.com
    软件文档知多少?
    地高人柳州地区高中校友大联盟 地高校友录,聚会活动,今日地高,母校追忆,校友今朝,职场生涯
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12333633.html
Copyright © 2011-2022 走看看