2016 Multi-University Training Contest 2 Eureka

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dd_lucky/article/details/51996584
Problem 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  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
 

Author
zimpha

题意:
 

给 n个点,大于等于2个在同一条直线上的点可以构成一个集合,问你现在有多少个集合;

思路:

首先对所有的点进行排序,统计出相同点的个数,然后对每个点做差,统计出可以组成的线段个数


代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxx=1015,mod=1e9+7;


struct point 
{
int x,y;
point(){}
point(int _x,int _y) {
x=_x,y=_y;
}
point operator -(const point &a)
{
return point(x-a.x,y-a.y);
}
bool operator <(const point &a)
{
return x<a.x||(x==a.x&&y<a.y);
}
bool operator ==(const point &a)
{
return x==a.x&&y==a.y;
}
void reduce()
{
int g=std::__gcd(abs(x),abs(y));
if(g) x/=g,y/=g;
}
}P[maxx],Q[maxx];
int pp[maxx],n;
void update(int &x,int y)
{
x+=y;
if(x>=mod) x-=mod;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
//memset(pp,0,sizeof pp);
//memset(Q,0,sizeof Q);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&P[i].x,&P[i].y);
pp[0]=1;
for(int i=1;i<=n;i++)
pp[i]=pp[i-1]*2%mod;
std::sort(P,P+n);
int m=0,cnt=0,ret=0;
for(int i=0;i<n;i++)
{
cnt=0,m=0;
for(int j=i+1;j<n;j++)
{
if(P[i]==P[j])cnt++;
else
Q[m++]=P[i]-P[j];
}
for (int j = 0; j < m; ++j) Q[j].reduce();
std::sort(Q,Q+m);
update(ret,pp[cnt]-1);
for(int xx=0,yy;xx<m;xx=yy)
{
for(yy=xx;Q[xx]==Q[yy]&&yy<m;yy++);
update(ret,1LL*pp[cnt]*(pp[yy-xx]-1)%mod);
}
}
printf("%d\n",ret);
}
return 0;
}


猜你喜欢

转载自blog.csdn.net/dd_lucky/article/details/51996584