HDU 5738 Eureka
来源:互联网 发布:专业调色软件app 编辑:程序博客网 时间:2024/05/21 08:44
http://acm.hdu.edu.cn/showproblem.php?pid=5738
第一步:推导公式发现对于给定的u、v,如果w要满足条件式,就必须与u、v共线。问题变为求点集中多少个子集(至少包含两个点,位置一样没关系)共线
第二步:将所有的点按x第一优先级、y第二优先级排序
第三步:对于当前的点u,计算所有排在它之后的点与其形成的向量,并化成最简的形式存在map里
这样之后遍历map能知道从这个点出发的所有方向,并在这个方向上点的个数。
第四步:如果不存在重点,也就是起点u的位置上只有一个点,那么对于某个方向上有m个点,我们就可以算出这个方向上子集的个数
2 ^ m - 1(那m个点每个考虑取或不取,然后减去全不取的一种情况)
但现在起点上可能不止一个点,如果照上面这样,每个方向都那么累加,就重复那些起点位置的点互相组合的情况
所以我们把起点重复的点所贡献的可能性独立出来。
从map我们可以得到0向量的个数,也就是u那个位置除了u自己其他也在那个位置点的个数,记作k
那么这些点互相组合的数目是2^(k+1) - (n+1) - 1 (k个点加上u这个点取或不取,减去只有一个点的情况,减去全不取的情况)
然后对于所有的非0向量,记那个方向上点的个数为m,其组合的数目为 (2^(k+1) - 1) * (2 ^ m -1) (起点处的点取或不取,减去全不取的情况) * (该方向上的点取或不取,减去全不取的情况)
第五步:对于每个点(位置相同的点只取一个)的每个方向,都做上述的累加得到答案。
//// main.cpp// 5738 Eureka//// Created by czf on 2017/4/20.// Copyright © 2017年 czf. All rights reserved.//#include <iostream>#include <algorithm>#include <map>using namespace std;typedef long long LL;struct Point { LL x, y; bool operator < (const Point & r) const { if (x == r.x) { return y < r.y; } return x < r.x; } bool operator == (const Point & r) const { return x == r.x && y == r.y; }};typedef Point Vect;const int maxn = 1000 + 100;const LL MOD = 1e9 + 7;map<Vect, LL> mp;map<Point, bool> vis;Point a[maxn];//化简向量Vect solve(LL tx, LL ty) { Vect temp; if (tx == 0 || ty == 0) { if (tx == 0 && ty == 0) { temp.x = 0; temp.y = 0; } else if (tx == 0) { temp.x = 0; temp.y = 1; } else { temp.x = 1; temp.y = 0; } } else { LL g = __gcd(tx, ty); temp.x = tx / g; temp.y = ty / g; } return temp;}LL qp(LL x, LL n) { LL ret = 1; while (n) { if (n & 1) ret = ((ret % MOD) * (x % MOD)) % MOD; n >>= 1; x = ((x % MOD) * (x % MOD)) % MOD; } return ret;}int main() { int T; scanf("%d",&T); while (T--) { int n; scanf("%d",&n); for (int i = 0; i < n; i ++) { scanf("%lld%lld",&a[i].x,&a[i].y); } sort(a, a+n); vis.clear(); Vect zero = (Point){0,0}; LL sum = 0; for (int i = 0; i < n; i ++) { if (vis[a[i]]) continue; vis[a[i]] = 1; mp.clear(); for (int j = i+1; j < n; j ++) { LL tx = a[j].x - a[i].x; LL ty = a[j].y - a[i].y; mp[solve(tx, ty)] ++; } LL k = mp[zero]; map<Vect, LL>::iterator it = mp.begin(); for (; it != mp.end(); it ++) { Vect v = it->first; if (v == zero) { sum = (sum + qp(2, k+1)) % MOD; sum = (sum - k - 2 + MOD) % MOD; } else { LL m = mp[v]; LL g1 = (qp(2, k+1) - 1 + MOD) % MOD; LL g2 = (qp(2, m) - 1 + MOD) % MOD; sum += g1 * g2 % MOD; } } } printf("%lld\n",sum % MOD); } return 0;}
0 0
- 【hdu 5738】Eureka
- HDU 5738 Eureka
- HDU 5738 Eureka
- HDU 5738 Eureka
- [HDU 5738] Eureka (计数)
- HDU 5738 Eureka(map瞎搞)
- HDU 5738 Eureka(计数)
- hdu 5738 Eureka 极角排序 计数
- hdu 5738 Eureka(组合数)
- hdu 5738 多校2 Eureka 【几何计数】
- hdu 5738 Eureka 极角排序
- HDU 5738 Eureka(组合数学)
- HDU 5738 Eureka(统计共线点对)
- HDU 5738 Eureka (from: 2016 Multi-University Training Contest 2)
- 2016 Multi-University Training Contest 2-1005---HDU 5738 Eureka
- 2016多校联赛2D Eureka(hdu 5738)
- HDU 5738 Eureka 2016多校合练contest2
- Hdu 5738 Eureka (组合数中档题)
- 动态规划—26,30滑雪
- Apache 80端口被占用
- TypeScript基本数据类型
- 使用HttpClient实现文件的上传
- org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 23 in XML document from
- HDU 5738 Eureka
- python实现的简易员工管理系统
- 数据库
- 前端入门DAY4-学习笔记
- 迭代器模式和原型模式
- Java并发编程:volatile关键字解析(三)
- 使用itms-services安装ipa
- JS --- 计算两个日期之间的天数
- 程序员为什么要会用Google谷歌搜索引擎