版权声明:本文为博主原创文章,未经博主允许不得转载。 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,v∈P,u≠v) are called best pair, if for every w∈P, f(u,v)≥g(u,v,w), where f(u,v)=(xu−xv)2+(yu−yv)2−−−−−−−−−−−−−−−−−−√ and g(u,v,w)=f(u,v)+f(v,w)+f(w,u)2.
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,v∈P,u≠v) are called best pair, if for every w∈P, f(u,v)≥g(u,v,w), where f(u,v)=(xu−xv)2+(yu−yv)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 (1≤n≤1000) -- then number of points.
Each of the following n lines contains two integers xi and yi (−109≤xi,yi≤109) -- coordinates of the i-th point.
The first line contains an integer n (1≤n≤1000) -- then number of points.
Each of the following n lines contains two integers xi and yi (−109≤xi,yi≤109) -- 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;
}