FZU 2110 Star

计算几何

训练的题目,给出n个点的坐标(整数),选3个点组成三角形问能形成多少个锐角三角形

直接暴力解决,用三个for循环枚举3个点(升序枚举避免重复),然后用余弦判断三角形中三个角是否为锐角

判断一个角为锐角:已知j,i,k三个点形成一个角,以i为交点向j,k做两个向量a,b,用余弦定理

cos = a*b/( |a| * |b| ) ,因为|a|*|b|必为正整数而且我们不是要算确切的角度只是判断锐,直,钝角所以直接用 a*b

a*b=0 , 直角

a*b>0 , 锐角或0度

a*b<0,钝角或180度

所以不用单纯靠 a*b 的正负来判断是什么叫,对于a*b>0的情况还要判断是否为0度

最后整个数据都是整型,操作也用整型不需要用浮点型,避免精度问题

#include <cstdio>
#include <cstring>
#include <utility>
using namespace std;
#define N 110

typedef long long ll;
typedef pair<ll , ll> pll;
pll p[N];
int n;

ll judge(pll a , pll b)
{
    ll c = a.first*b.first + a.second*b.second ;
    if(c<=0 || (c>0 && a.first*b.second == a.second*b.first))
        return -1;
    return 1;
}

void solve()
{
    ll count = 0;
    for(int i=0; i<n; i++)
        for(int j=i+1; j<n; j++)
            for(int k=j+1; k<n; k++)
            {
                ll f[3];
                pll a,b;
                a.first=p[j].first-p[i].first;
                a.second=p[j].second-p[i].second;
                b.first=p[k].first-p[i].first;
                b.second=p[k].second-p[i].second;
                f[0]=judge(a,b);

                a.first=p[i].first-p[j].first;
                a.second=p[i].second-p[j].second;
                b.first=p[k].first-p[j].first;
                b.second=p[k].second-p[j].second;
                f[1]=judge(a,b);

                a.first=p[i].first-p[k].first;
                a.second=p[i].second-p[k].second;
                b.first=p[j].first-p[k].first;
                b.second=p[j].second-p[k].second;
                f[2]=judge(a,b);

                ll ok=1;
                for(int i=0; i<3; i++)
                    if(f[i]<0)
                    { ok=0; break;}
                count += ok;
            }
    printf("%I64d\n",count);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%I64d%I64d",&p[i].first , &p[i].second);
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/scau20110726/p/3030438.html