zoukankan      html  css  js  c++  java
  • hdu5785(极角排序求所有锐角钝角个数)

    做法很显然,求出所有的锐角和钝角就能求出有多少个锐角三角形了。

    我用了愚钝的方法,写了两三个小时。。。

    看了下别人简单的代码。学习了下做法。

    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++;//找出<180的角
        while(temp[l]-temp[j]<0.5*PI&&l<=2*cnt)l++;//找出<90度的角
        while(temp[le]-temp[j]<=eps&&le<=2*cnt)le++;//排除一条直线的情况
        ans1=ans1+r-l;
        ans2=ans2+l-le;
    }

    再附上自己拙略的代码:

    //
    //  main.cpp
    //  hdu5784
    //
    //  Created by New_Life on 16/8/10.
    //  Copyright © 2016年 chenhuan001. All rights reserved.
    //
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    #define PI acos(-1.0)
    
    struct point
    {
        int x,y;
        double shita;
    }g[2020],tg[2020];
    
    int cmp(point p1,point p2)
    {
        return p1.shita<p2.shita;
    }
    
    double operator*(point p1, point p2) // 计算叉乘 p1 × p2
    {
        return ((long long)p1.x * p2.y - (long long)p2.x * p1.y);
    }
    double operator&(point p1, point p2) { // 计算点积 p1·p2
        return ((long long)p1.x * p2.x + (long long)p1.y * p2.y);
    }
    
    
    int dsub(int p1,int p2)
    {
        return (tg[p1]*tg[p2]<=0)&&( (tg[p1]&tg[p2])>0 );
    }
    
    int savenum[2020];
    
    int main(int argc, const char * argv[]) {
        int n;
        while(cin>>n)
        {
            for(int i=0;i<n;i++)
            {
                scanf("%d%d",&g[i].x,&g[i].y);
            }
            long long ans = 0;
            for(int i=0;i<n;i++)
            {
                int cnt = 0;
                for(int j=0;j<n;j++)
                {
                    if(j==i) continue;
                    int tx = g[j].x - g[i].x;
                    int ty = g[j].y - g[i].y;
                    tg[cnt].x = tx; tg[cnt].y = ty;
                    tg[cnt++].shita = atan2(ty, tx);
                }
                if(cnt < 2) continue;
                sort(tg,tg+cnt,cmp);
                memset(savenum,0,sizeof(savenum));
                
                int scnt= cnt;
                int tcnt = 0;
                savenum[tcnt++] = 1;
                for(int j=1;j<cnt;j++)
                {
                    if( tg[j]*tg[tcnt-1]==0 && ( (tg[j]&tg[tcnt-1])>0 ) )
                    {
                        savenum[tcnt-1]++;
                    }
                    else
                    {
                        tg[tcnt] = tg[j];
                        savenum[tcnt] = 1;
                        tcnt++;
                    }
                }
                
                cnt = tcnt;
                for(int j=0;j<cnt;j++)
                {
                    ans += savenum[j]*(savenum[j]-1);
                }
                
                if(cnt==1) continue;
                tcnt = 0;
                int lf=0,rt=1;
                
                while( dsub(0,lf) ){
                    tcnt += savenum[lf];
                    lf = (lf-1+cnt)%cnt;
                    if(lf == 0) break;
                }
                lf = (lf+1)%cnt;
                while( rt!=0 && dsub(rt,0) ) tcnt+=savenum[rt],rt = (rt+1)%cnt;
                //rt = (rt-1+cnt)%cnt;
                ans += savenum[0]*(tcnt-savenum[0]);
                ans -= 2*savenum[0]*(scnt-tcnt);
                
                for(int j=1;j<cnt;j++)
                {
                    if(j == lf)
                    {
                        tcnt -= savenum[lf];
                        lf = (lf+1)%cnt;
                    }
                    if(j == rt)
                    {
                        tcnt += savenum[j];
                        rt = (rt+1)%cnt;
                    }
                    while( !dsub(j,lf) )
                    {
                        tcnt -= savenum[lf];
                        lf= (lf+1)%cnt;
                        //if(lf == j) break;
                    }
                    while(rt!=j && dsub(rt,j) ) tcnt+=savenum[rt],rt=(rt+1)%cnt;
                    ans += savenum[j]*(tcnt-savenum[j]);
                    ans -= 2*savenum[j]*(scnt-tcnt);
                }
            }
            cout<<ans/6<<endl;
        }
        return 0;
    }
    /*
     4
     0 0
     0 1
     1 0
     1 1
     9
     0 0
     2 0
     0 1
     2 1
     1 0
     1 1
     0 2
     1 2
     2 2
     4
     0 0
     1 1
     2 2
     3 3
     5
     0 0
     1 1
     2 2
     -1 0
     10000 0
     */
  • 相关阅读:
    eclipse如何卸载adt插件
    Android中的Toast.LENGTH_SHORT
    Frogger
    - Oil Deposits 深搜,就是所谓的dfs
    Aggressive cows
    Phone List
    Word Amalgamation
    Street Numbers
    Charm Bracelet——背包问题
    函数参考
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5759948.html
Copyright © 2011-2022 走看看