Professor Zhang draws
n
points on the plane, which are conveniently labeled by
1,2,...,n
. The
i
-th point is at
(x
i
,y
i
)
. Professor Zhang wants to know the number of best sets. As the value could be very large, print it modulo
10
9
+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)=(x
u
−x
v
)
2
+(y
u
−y
v
)
2
−
−
−
−
−
−
−
−
−
−
−
−
−
−
−
−
−
−
√
and
g(u,v,w)=f(u,v)+f(v,w)+f(w,u)
2
.
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
x
i
and
y
i
(−10
9
≤x
i
,y
i
≤10
9
)
-- coordinates of the
i
-th point.
3 3 1 1 1 1 1 1 3 0 0 0 1 1 0 1 0 0
4 3 0
题意:
满足题意的点集为共线点集和相同点集,一个集合至少两个点;
额上面是搜到的题意,其实就是问任意多个在一条直线上点,构成一个集合。问集合数多少。例如,同一条直线有三个点,a,b,c。ab,bc,ac,abc共有四个点集合,这里有方向。
因为有方向,要排个序。因为有相同点的存在,求出相同点多少个,然后从相同点抽取i个点,2^i个,乘上其他在这条直线上的点个数的2^k个。自己单独集合单算。具体公式: (2 m −1−m)+sum((s m −1)∗(2 k −1)) 。公式摘自http://blog.youkuaiyun.com/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;
}