map+组合数学_____Eureka( POJ 5738 2016多校第二场)

来源:互联网 发布:国际期货软件下载 编辑:程序博客网 时间:2024/06/06 02:58

roblem Description
Professor Zhang draws n points on the plane, which are conveniently labeled by 1,2,...,n. The i-th point is at (xi,yi). Professor Zhang wants to know the number of best sets. As the value could be very large, print it modulo 109+7.

A set P (P contains the label of the points) is called best set if and only if there are at least one best pair in P. Two numbers u and v (u,vP,uv) are called best pair, if for every wPf(u,v)g(u,v,w), where f(u,v)=(xuxv)2+(yuyv)2−−−−−−−−−−−−−−−−−−√ and g(u,v,w)=f(u,v)+f(v,w)+f(w,u)2.
 
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1n1000) -- then number of points.

Each of the following n lines contains two integers xi and yi (109xi,yi109) -- coordinates of the i-th point.
 
Output
For each test case, output an integer denoting the answer.
 
Sample Input
3
3
1 1
1 1
1 1
3
0 0
0 1
1 0
1
0 0
 
Sample Output
4
3
0
 
题意:

给定n个平面点,对于一个点集合P,存在一对点u,v.任意w∈P,u,v间的距离≥u,v,w,间距离和的一半。求这样的集合数量。



分析:

化简公式可知,当集合中的所有点共线的时候则集合满足题意。

用最简即约分数表示斜率然后用map存,然后就是组合数学的事情,注意,因为可能有多个点同坐标,所以要特殊处理!!!


代码:

#include<stdio.h>#include<algorithm>#include<string.h>#include<map>using namespace std;typedef long long ll;const ll mod = 1e9 + 7;struct node{    ll x,y;    node(){}    node(ll a,ll b){ x = a, y = b;    }    bool operator < (node b) const    {        if( x == b.x) return y < b.y;        return x < b.x;    }};node p[1010];map<node,ll> mpt;int n;ll gcd(ll a,ll b){    return b == 0 ? a : gcd(b,a%b);}bool cmp(node a, node b){    if(a.x == b.x)        return a.y < b.y;    return a.x < b.x;}ll pow2(ll a,ll b){    if( b == 0) return 1;    if( b == 1) return a%mod;    if( b % 2 == 0) return pow2(a*a%mod,b/2);    return pow2(a*a%mod,b/2)*a%mod;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        ll cnt = 0;        scanf("%d",&n);        for(int i = 0 ; i < n ; i ++)scanf("%lld%lld",&p[i].x,&p[i].y);        sort(p,p+n);        for(int i = 0 ; i < n ; i ++)        {            mpt.clear();            ll step = 0;            for(int j = i + 1 ; j < n ; j ++)            {                if(p[i].x == p[j].x && p[i].y == p[j].y)                {                    step ++;                }                else                {                    ll tx = p[j].x - p[i].x;                    ll ty = p[j].y - p[i].y;                    ll g = gcd(tx,ty);                    if( g != 0)                    {                        mpt[node(tx/g,ty/g)] ++;                    }                }            }            if(step >= 1) cnt = (pow2(2,step)+cnt-1)%mod;            for(map<node,ll>::iterator it = mpt.begin() ; it != mpt.end() ; it ++)            {                ll k = it->second;                cnt = (cnt + (pow2(2,k)-1)* pow2(2,step))%mod;            }        }        printf("%lld\n",cnt);    }    return 0;}



0 0
原创粉丝点击