您的位置:首页 > 其它

map+组合数学_____Eureka( POJ 5738 2016多校第二场)

2016-08-24 19:57 148 查看
roblem 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.

 

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.

 

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
 

题意:

给定n个平面点,对于一个点集合P,存在一对点u,v.任意w∈P,u,v间的距离≥u,v,w,间距离和的一半。求这样的集合数量。

分析:

化简公式可知,当集合中的所有点共线的时候则集合满足题意。

用最简即约分数表示斜率然后用map存,然后就是组合数学的事情,注意,因为可能有多个点同坐标,所以要特殊处理!!!

代码:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<map>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
struct node
{
ll x,y;
node(){}
node(ll a,ll b){ x = a, y = b;
}
bool operator < (node b) const
{
if( x == b.x) return y < b.y;
return x < b.x;
}
};
node p[1010];
map<node,ll> mpt;
int n;

ll gcd(ll a,ll b)
{
return b == 0 ? a : gcd(b,a%b);
}
bool cmp(node a, node b)
{
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
ll pow2(ll a,ll b)
{
if( b == 0) return 1;
if( b == 1) return a%mod;
if( b % 2 == 0) return pow2(a*a%mod,b/2);
return pow2(a*a%mod,b/2)*a%mod;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll cnt = 0;
scanf("%d",&n);
for(int i = 0 ; i < n ; i ++)scanf("%lld%lld",&p[i].x,&p[i].y);
sort(p,p+n);
for(int i = 0 ; i < n ; i ++)
{
mpt.clear();
ll step = 0;
for(int j = i + 1 ; j < n ; j ++)
{
if(p[i].x == p[j].x && p[i].y == p[j].y)
{
step ++;
}
else
{
ll tx = p[j].x - p[i].x;
ll ty = p[j].y - p[i].y;
ll g = gcd(tx,ty);
if( g != 0)
{
mpt[node(tx/g,ty/g)] ++;
}
}
}
if(step >= 1) cnt = (pow2(2,step)+cnt-1)%mod;
for(map<node,ll>::iterator it = mpt.begin() ; it != mpt.end() ; it ++)
{
ll k = it->second;
cnt = (cnt + (pow2(2,k)-1)* pow2(2,step))%mod;
}
}
printf("%lld\n",cnt);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息