Strange Tax Calculation UVA - 11529 (幾何 求三角形內點數)

題目

https://vjudge.net/problem/UVA-11529

題意

給出若干個點,保證任意三點不共線,任意選三個點作爲三角行,其他點若又在該三角形內,則算是該三角形內部的點,問所有情況的三角形平均每個三角形有多少個內部點。

思路

三角形的總數很容易求C(3n),現在就是要求各個三角形內部點的總數,同樣我們可以反過來,求每個點在多少個三角形的內部。
然後我們確定一個點,求該點在多少個三角的內部,剩餘n-1個點,可以組成C(3n−1])個三角形,所以只要求出該點在哪些三角形的外部即可。

紅色點爲選中的點,將周圍點按照與選中點的極角進行排序,每次枚舉一點,它的極角爲a,所有極角小於a+pi的點,這些點組成的三角形,選中點一定在外部。處理一週的方式是將點的數組擴大兩倍,將所有點的極角加上pi有保留在延長的數組中。
代碼

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
 
using namespace std;
const int N = 1205;
const double pi = 4 * atan(1.0);
const double eps = 1e-9;
 
int n;
double s, r[2*N];
struct point {
    double x, y;
}p[N];
 
double Count (int d) {
    int c = 0, mv = 0;
    for (int i = 0; i < n; i++) {
        if (i == d)
            continue;
 
        double a = atan2(p[i].y-p[d].y, p[i].x-p[d].x);
        r[c] = a;
        r[c+n-1] = a + 2*pi;
        c++;
    }
 
    c = 2 * n - 2;
    sort(r, r + c);
 
    double ans = 0;
 
    for (int i = 0; i < n-1; i++) {
        double tmp = r[i] + pi;
 
        while (tmp > r[mv])
            mv++;
        double cnt = mv - i - 1;
        ans = ans + cnt * (cnt-1) / 2;
    }
    return s - ans;
}
 
double solve () {
    s = (n-1) * (n-2) * (n-3) / 6.0;
    double c = n * (n-1) * (n-2) / 6.0;
    double ans = 0;
 
    for (int i = 0; i < n; i++)
        ans += Count(i);
 
    return ans / c;
}
 
int main () {
    int cas = 1;
    while (scanf("%d", &n) == 1 && n) {
        for (int i = 0; i < n; i++)
            scanf("%lf%lf", &p[i].x, &p[i].y);
        printf("City %d: %.2lf\n", cas++, solve());
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章