問題への解決策LA4064

タイトルエフェクトデータの複数のセットは、データの各セットは正の整数で指定された(n(nは\ 1200当量を\ )\) と面内の\(N- \)点の座標。必要な出力とすべての急性直角三角形の数。

分析この質問とのUVA 11529特にあまりにもデータ範囲、などです。

我々は、逆側から鈍角(なぜ)の数であり、統計的鈍角三角形の数を進みます。その後の練習を原点と各ポイントを列挙するのと同じ質問を使用し、他のポイントは、ソート、極角の原点に計算されます。各ポイントは、次に列挙され\(A \)二つのポインタ維持することにより([ang_A + \ FRAC {\ \ \ PI} {2}、ang_A + \ PI])を、全ての点の数、鈍角となっている数。モノトーンの複雑さが増加しないため、全体的な複雑さがある(O(N-2 ^ \ Nログ)\)\

精度の問題に注意して、最高の浮動小数点数として保存された座標、私はWA持っているこれのために\(3 \)回。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1205;
const double PI = acos(-1.0), eps = 1E-10;

ll n, t, tot, now1, now2;
ll ans, cnt;
double ang[maxn * 2];
struct Point {
    double x, y;
} p[maxn];

ll C(ll n, ll m)
{
    if(n < m) return 0;
    
    ll res = 1;
    for(ll i = 1; i <= m; ++i)
        res = res * (n - i + 1) / i;
    return res;
}

ll count(int x)
{
    tot = 0, now1 = 1, now2 = 1, cnt = 0;   
    for(ll i = 1; i <= n; ++i) {
        if(i == x) continue;
        ang[++tot] = atan2(p[i].y - p[x].y, p[i].x - p[x].x);
        
        if(ang[tot] < 0) ang[tot] += 2 * PI;
        ang[tot + n - 1] = ang[tot] + 2 * PI;
    }
    
    sort(ang + 1, ang + tot * 2 + 1);
    
    for(ll i = 1; i <= tot; ++i) {
        while(ang[now1] - ang[i] <= PI * 0.5 - eps) ++now1;
        while(ang[now2] - ang[i] < PI) ++now2;
        cnt += now2 - now1;
    }
    
    return cnt;
}

int main()
{
    while(~scanf("%lld", &n) && n) {
        ans = 0;
        
        for(int i = 1; i <= n; ++i)
            scanf("%lf%lf", &p[i].x, &p[i].y);
        
        for(int i = 1; i <= n; ++i)
            ans += count(i);
            
        printf("Scenario %lld:\nThere are %lld sites for making valid tracks\n", ++t, C(n, 3) - ans);
    }
}

おすすめ

転載: www.cnblogs.com/whx1003/p/12297626.html