HDU 5738 Eureka 2016多校合练contest2

传送门

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 wP, f(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

题意:

满足题意的点集为共线点集和相同点集,一个集合至少两个点; 

额上面是搜到的题意,其实就是问任意多个在一条直线上点,构成一个集合。问集合数多少。例如,同一条直线有三个点,a,b,c。ab,bc,ac,abc共有四个点集合,这里有方向。

因为有方向,要排个序。因为有相同点的存在,求出相同点多少个,然后从相同点抽取i个点,2^i个,乘上其他在这条直线上的点个数的2^k个。自己单独集合单算。具体公式:(2 m 1m)+sum((s m 1)(2 k 1)) 。公式摘自http://blog.csdn.net/lhfl911/article/details/52004755









#include<stdio.h>
#include<iostream>
#include<math.h>
#include<stdlib.h> 
#include<string.h>
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
#include<map>
#include<iterator>
#include<math.h>
#include<set>
using namespace std;
#define MAX 1000000007
long long gcd(long long x,long long y)
{  
    if(y==0) return x;  
    else return(gcd(y,x%y));  
}  
long long mod_exp(long long a, long long b,long long c) 
{
    long long res, t;
    res = 1 % c; 
    t = a % c;
    while (b)
    {
        if (b & 1)
        {
            res = res * t % c;
        }
        t = t * t % c;
        b /= 2 ;
    }
    return res;
}
struct Point
{
    long long x;long long y;
    bool operator<(const Point&x)const{
        if(this->x==x.x)
            return this->y<x.y;
        else
            return this->x<x.x;
    }
}pp[1100];
map<Point,long long> f;
map<Point,long long>::iterator it;
map<Point,long long>g;
bool cmp(Point x,Point y)
{
    return x<y;

}
int main()
{
    long long t,n,sum,ans,index,i,j;
    scanf("%lld",&t);
    while(t--)
    {
        g.clear();
        f.clear();
        ans=0;
        scanf("%lld",&n);
        for(i=0;i<n;i++)
        {
            scanf("%lld %lld",&pp[i].x,&pp[i].y);
        }
        sort(pp,pp+n);
        for(i=0;i<n;i++)
        {
            
            if(g[pp[i]])
                continue;
            f.clear();
            for(j=i+1;j<n;j++)
            {
                long long x=pp[j].x-pp[i].x;
                long long y=pp[j].y-pp[i].y;
                if(x<0)
                {
                    x=-x;
                    y=-y;
                }
                long long GCD=gcd(x,abs(y));
                if(x!=0&&y!=0)
                {
                    if(x==0)
                        y=1;
                    if(y==0)
                        x=1;
                }
                if(GCD!=0)
                {
                    x/=GCD;
                    y/=GCD;
                }
                Point temp;
                temp.x=x;
                temp.y=y;
                f[temp]++;
            }
            long long k;
            Point ggg;
            ggg.x=0;
            ggg.y=0;
            long long temp;
            temp=f[ggg];
            for(it=f.begin();it!=f.end();it++)
            {
                if(it->first.x==0&&it->first.y==0)
                {
                    k=mod_exp(2,it->second+1,MAX);
                    k=k-it->second-2;
                    ans+=k;        
                    ans%=MAX;
                }
                else
                {
                    k=mod_exp(2,it->second,MAX);
                    k=k-1;
                    ans+=(k*(mod_exp(2,temp+1,MAX)-1));
                    ans%=MAX;
                }
            }
            g[pp[i]]=1;
        }
        ans%=MAX;
        printf("%lld\n",ans);
    }
    return 0;
} 



猜你喜欢

转载自blog.csdn.net/yizhangbiao/article/details/52045209