• 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;
    }
  • 相关阅读:
    DNS隧道
    记录上锁(fcntl)
    posix对线程的调整
    MySQL创建存储过程
    MySQL的WHERE语句中BETWEEN与IN的用法和他们的区别
    mysql中distinct
    线程的工作方式-流水线
    可执行程序的生成过程
    线程高级编程
    time函数及其用法
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3030438.html
Copyright © 2020-2023  润新知