您的位置:首页 > 其它

HDU 5738 Eureka 2016多校合练contest2

2016-07-27 14:47 489 查看
传送门

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.

[align=left]Input[/align]
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.

[align=left]Output[/align]
For each test case, output an integer denoting the answer.

[align=left]Sample Input[/align]

3
3
1 1
1 1
1 1
3
0 0
0 1
1 0
1
0 0


[align=left]Sample Output[/align]

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.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: