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]
[align=left]Sample Output[/align]
题意:
满足题意的点集为共线点集和相同点集,一个集合至少两个点;
额上面是搜到的题意,其实就是问任意多个在一条直线上点,构成一个集合。问集合数多少。例如,同一条直线有三个点,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。
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; }
相关文章推荐
- GPL,LGPL和BSD等协议注意事项
- GPL,LGPL和BSD等协议注意事项
- 清理sqlserver 2012 日志文件
- HDU 5758 Explorer Bo (树形DP)
- poj1201 intervals
- Linux反向过滤导致网卡无法从外网ping通
- HDU5733 tetrahedron[计算几何]
- 三种主流的WebService实现方案(REST/SOAP/XML-RPC)简述及比较
- Netperf - The fastest TCP connection with Multipath TCP
- 字节流和字符流的区别
- jsp el比较字符串
- 关于无法加载DLL"***.dll":找不到指定的模块(异常来自HRESULT:0x8007007E)问题的解决办法
- 源码-PL/SQL从入门到精通-第十八章-PL/SQL性能优化建议-Part 1
- OpenCV学习笔记——滑动条开关
- Intellij Idea2016.2开发工具注册
- linux查看版本号、更改主机名、位数
- Inno Setup 注册表启动项 修改注册表
- 门户更新开发计划
- $.ajax()
- 计词unigram和bigram的频次