uva 11123 - Counting Trapizoid(容斥+幾何)

來源:互聯網
上載者:User

標籤:style   http   color   width   os   for   

題目連結:uva 11123 - Counting Trapizoid

題目大意:給定若干個點,問有多少種梯形,不包括矩形,梯形的面積必須為正數。因為是點的集合,所以不會優重複的點。

解題思路:枚舉兩兩點,求出該條直線,包括斜率k,位移值c,以及長度l。已知梯形的性質,一對對邊平行,也就是說一對平行但是不相等的邊。

所以將所有線段按照斜率排序,假設對於某一斜率,有m條邊,那麼這m條邊可以組成的含平行對邊的四邊形有C(2m),要求梯形還要減掉長度相同以及共線的情況,分別對應的是l相同和c相同,但是根據容斥原理,要加回l和c均相等的部分。

#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <algorithm>using namespace std;const int N = 205;const double eps = 1e-9;const double pi = 4 * atan(1.0);struct line {    double k, c, l;    line (double k, double c = 0, double l = 0) {        this->k = k;        this->c = c;        this->l = l;    }    friend bool operator < (const line& a, const line& b) {        return a.k < b.k;    }};struct state {    double c, l;    state (double c, double l) {        this->c = c;        this->l = l;    }};int n;double x[N], y[N];vector<line> set;vector<state> g;inline double distant (double xi, double yi) {    return xi * xi + yi * yi;}inline double cal (int a, int b) {    if (x[a] == x[b])        return x[a];    return y[a] - x[a] * ( (y[a] - y[b]) / (x[a] - x[b]) );}inline int C (int a) {    if (a < 1)        return 0;    return a * (a - 1) / 2;}inline bool cmpC (const state& a, const state& b) {    if (fabs(a.c-b.c) > eps)        return a.c < b.c;    return a.l < b.l;}inline bool cmpL (const state& a, const state& b) {    return a.l < b.l;}int judge () {    sort(g.begin(), g.end(), cmpC);    int ans = 0, cnt = 1, tmp = 1;    /*    for (int i = 0; i < g.size(); i++) {        printf("%lf %lf\n", g[i].c, g[i].l);    }    printf("\n");    */    for (int i = 1; i < g.size(); i++) {        if (fabs(g[i].c - g[i-1].c) > eps) {            ans = ans + C(cnt) - C(tmp);            cnt = 0;            tmp = 0;        }        if (fabs(g[i].l - g[i-1].l) > eps) {            ans = ans - C(tmp);            tmp = 0;        }        tmp++;        cnt++;    }    ans = ans + C(cnt) - C(tmp);    sort(g.begin(), g.end(), cmpL);    cnt = 1;    for (int i = 1; i < g.size(); i++) {        if (fabs(g[i].l - g[i-1].l) > eps) {            ans = ans + C(cnt);            cnt = 0;        }        cnt++;    }    ans = ans + C(cnt);    return ans;}int solve () {    int ans = 0;    if (set.size() == 0)        return 0;    g.clear();    g.push_back(state(set[0].c, set[0].l));    for (int i = 1; i < set.size(); i++) {        //printf("%d %lf!!!!!!!\n", i, set[i].k);        if (fabs(set[i].k - set[i-1].k) > eps) {            ans += C(g.size()) - judge();            g.clear();        }        g.push_back(state(set[i].c, set[i].l));    }    ans += C(g.size()) - judge();    return ans;}int main () {    int cas = 1;    while (scanf("%d", &n) == 1 && n) {        set.clear();        for (int i = 0; i < n; i++) {            scanf("%lf%lf", &x[i], &y[i]);            for (int j = 0; j < i; j++)                set.push_back(line( atan2(y[j]-y[i], x[j]-x[i]), cal(i, j), distant(y[i]-y[j], x[i]-x[j]) ));        }        for (int i = 0; i < set.size(); i++) {            if (set[i].k < eps)                set[i].k += pi;        }        sort(set.begin(), set.end());        /*        for (int i = 0; i < set.size(); i++) {            printf("%d %lf %lf %lf\n", i, set[i].k, set[i].c, set[i].l);        }        */        printf("Case %d: %d\n", cas++, solve());    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.