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
 */
原文地址:https://www.cnblogs.com/chenhuan001/p/5759948.html