hdu 5738 多校2 Eureka 【几何计数】

来源:互联网 发布:久其通用数据平台 编辑:程序博客网 时间:2024/06/05 10:57

思路:
满足题意的点集为共线点集和相同点集,一个集合至少两个点;
无重复枚举每个点,找出相同点个数m,共线点个数ki(多条线),
包含此点的点集个数为(2m1m)+sum((sm1)(2k1))
累加

#include <cstdio>#include <cstring>#include <map>#include <algorithm>using namespace std;typedef long long LL;const int MOD = 1e9 + 7;LL gcd(LL a, LL b){    if(!b)        return a;    return gcd(b, a%b);}struct point{    int x, y;    friend bool operator==(const point &a, const point &b)    {        return a.x == b.x && a.y == b.y;    }    friend bool operator<(const point &a, const point &b)    {        if(a.x == b.x)            return a.y < b.y;        else            return a.x < b.x;    }};class line{    LL a, b;public:    line(point g, point h)    {        a = h.y - g.y;        b = g.x - h.x;        LL d = gcd(a, b);        a /= d;        b /= d;        if(a < 0)        {            a = -a;            b = -b;        }    }    friend bool operator<(const line &t, const line &t1)    {        if(t.a == t1.a)            return t.b < t1.b;        else            return t.a < t1.a;    }};point p[1010];LL fp[1010];void init(){    fp[0] = 1;    for(int i = 1; i <= 1000; i++)    {        fp[i] = fp[i-1] << 1;        fp[i] %= MOD;    }}int main(int argc, char const *argv[]){    init();                             int t;    scanf("%d", &t);    while(t--)    {        int n;        scanf("%d", &n);        for(int i = 0; i < n; i++)            scanf("%d%d", &p[i].x, &p[i].y);        sort(p, p+n);        LL ans = 0;        for(int i = 0; i < n; i++)        {            int m = 1;            while(i+1 < n && p[i] == p[i+1])            {                m++;                i++;            }            ans += (fp[m] - 1 - m);      //相同点集            ans %= MOD;            map<line, int> l;            l.clear();            for(int j = i+1; j < n; j++)                l[line(p[i], p[j])] ++;            for(map<line, int>::iterator it = l.begin(); it != l.end(); it++)            {                ans += (fp[m] - 1) * (fp[it->second] - 1);  //共线点集                ans %= MOD;            }        }        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击