2016 Multi-University Training Contest 2 - 1005 (hdu5738)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5738
题目大意:给定平面上的n个点,一个集合合法当且仅当集合中存在一对点u,v,对于集合中任意点w,均有dis(u,v)≥[dis(u,v)+dis(u,w)+dis(v,w)]/2。其中dis(A,B)为A,B两点的欧几里得距离。问你这样的合法集合有多少个。数据范围:1≤n≤1000。
解题思路:对于所给条件简单分析一下就能转化题意,实际上是在求有多少个集合满足集合内的点都在同一直线上。
比赛时的思路一直是,由于可能有重点,于是把重点整合到一个集合里,记一下集合里的个数cnt,那么对于这样一个重点的集合,从中任选至少两个都能作为合法点集,因此对答案的贡献是(2^cnt - cnt - 1)。下面考虑非重点,枚举重点集,对其他重点集按到此点集的距离从小到大排序,再依次枚举,用map记录一下斜率,就能在枚举过程中得到两个重点集之间的点个数K(也就是有多少个点也是这个斜率),对答案的贡献就是(2^cnt1 - 1)*(2^cnt2 - 1)*(2^K)。这样做思路应该没什么问题,只是常数比较大,代码难度也不小。一直到比赛结束也一直WA。
后来看了题解,思路比较清楚。对于这种数方案,要不重不漏的题目要记得使用有序化思想。而在二维坐标中,很常用的两种排序就是x,y双关键字排序,还有极角排序。
首先我们对这n个点做双关键字排序,然后对于x相同的点,个数为cnt,那么对答案的贡献就是(2^cnt - cnt - 1),然后对于每个重点集,对它右面的点做极角排序,做这个排序的意义在于以下就把同一斜率的点搞到了一起,方便计算了。假设当前极角上有p个点那么对答案的贡献就是(2^cnt - 1)*(2^p - 1)。
值得注意的也是十分重要的,就是极角排序的正确做法。首先计算dx, dy,并除掉abs(gcd(dx,dy)),一定要取绝对值!!不然会WA得不明所以!!然后cmp()的时候不要把斜率化成小数比较,直接dyA*dxB<dxA*dyB这样比较可避免精度问题。
总之这道题思想难度不是很大,但是需要的技巧比较多,细节也比较多,是值得一写的题目。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL; const int MaxN = , Pt = 1e9 + ;
struct Point {
int x, y, dx, dy;
}a[MaxN + ], b[MaxN + ];
int T, n;
LL Pow[MaxN + ];
LL ans; int Gcd(int x, int y)
{
if (y == ) return x;
return Gcd(y, x % y);
} void Init()
{
scanf("%d", &n);
Pow[] = ;
for (int i = ; i <= n; i++) {
scanf("%d%d", &a[i].x, &a[i].y);
Pow[i] = (Pow[i - ] * ) % Pt;
}
} bool cmp(Point A, Point B) {
if (A.x == B.x) return A.y < B.y;
return A.x < B.x;
} bool cmp2(Point A, Point B) {
return (LL)A.dy * B.dx < (LL)A.dx * B.dy;
} void Solve()
{
ans = ;
sort(a + , a + n + , cmp);
int L = , R = ;
while (L <= n) {
while (R < n && a[R + ].x == a[R].x) R++;
//printf("%d %d\n", L, R);
ans = (ans + Pow[R - L + ] - - (R - L + )) % Pt;
int l = L, r = L;
while (l <= R) {
while (r < R && a[r + ].y == a[r].y) r++;
//printf("**%d %d\n", l, r);
int tot = ;
for (int i = R + ; i <= n; i++) {
b[++tot].dx = a[i].x - a[l].x;
b[tot].dy = a[i].y - a[l].y;
int D = Gcd(b[tot].dx, b[tot].dy);
if (D < ) D = -D;
b[tot].dx /= D; b[tot].dy /= D;
}
sort(b + , b + tot + , cmp2);
int cnt = ;
for (int i = ; i <= tot; i++) {
if (i == tot || cmp2(b[i], b[i + ])) {
ans = (ans + (Pow[r - l + ] - ) * (Pow[cnt] - )) % Pt;
cnt = ;
}else cnt++;
}
l = r + ; r = r + ;
}
L = R + ; R = R + ;
}
printf("%I64d\n", ans);
} int main()
{
scanf("%d", &T);
for (int i = ; i <= T; i++) {
Init();
Solve();
}
}
2016 Multi-University Training Contest 2 - 1005 (hdu5738)的更多相关文章
- 2016 Al-Baath University Training Camp Contest-1
2016 Al-Baath University Training Camp Contest-1 A题:http://codeforces.com/gym/101028/problem/A 题意:比赛 ...
- hdu 4939 2014 Multi-University Training Contest 7 1005
Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- 2016 Multi-University Training Contest 2 - 1005 Eureka
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5738 题目大意:给定平面上的n个点,一个集合合法当且仅当集合中存在一对点u,v,对于集合中任意点w,均 ...
- 2016 Multi-University Training Contest 4 - 1005 (hdu5768)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768 题目大意:给你区间[L,R],问你[L, R]中有多少个数字x满足x%7=0且x%p[i]≠a[ ...
- 2016 Al-Baath University Training Camp Contest-1 E
Description ACM-SCPC-2017 is approaching every university is trying to do its best in order to be th ...
- 2016 Al-Baath University Training Camp Contest-1 A
Description Tourist likes competitive programming and he has his own Codeforces account. He particip ...
- 2016 Al-Baath University Training Camp Contest-1 J
Description X is fighting beasts in the forest, in order to have a better chance to survive he's gon ...
- 2016 Al-Baath University Training Camp Contest-1 I
Description It is raining again! Youssef really forgot that there is a chance of rain in March, so h ...
- 2016 Al-Baath University Training Camp Contest-1 H
Description You've possibly heard about 'The Endless River'. However, if not, we are introducing it ...
随机推荐
- C#获取单元格值(使用NPOI插件)
/// <summary> /// 获取单元格的值 /// </summary> /// <param name="item"></par ...
- LDAP环境搭建 OpenLDAP和phpLDAPadmin -- yum版
前言: 前两天公司要求做一个使用LDAP和Kerberos做一个认证授权系统,然后开始学习LDAP相关知识,期间找了不少博客按照步骤来安装,可是很多博客在配置的时候,都会遇到安装过程中一两个问题卡 ...
- [例] 用MappedByteBuffer更新文件内容
import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; impor ...
- hdu1166 敌兵布阵 线段树(区间更新)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 简述wcf应用
一.新建wcf 如下图:wcf可以简历俩种形式 1.库文件,就是一个类库文件,可以用windows服务或控制台开启. 2.服务应用程序,可以直接IIS上面发布. 二.库文件自动生成的类 接口类 usi ...
- ExtJS 开发总结
1. ExtJS的定位是RIA,和Prototype.jQuery等类库的定位不同.使用ExtJS做开发,就是意味着以客户端开发为主,不然就不叫RIA框架了,而Prototype.jQuery等只是辅 ...
- protobuf在c++的使用方法以及在linux安装
https://blog.csdn.net/wangyin668/article/details/80046798 https://www.cnblogs.com/zhouyang209117/p ...
- http 协议的简单学习 虽然有点老但是 还不错
HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...
- Easy Touch 摇感控制人物移动
Easy Touch 摇感控制人物移动 public class joystick : MonoBehaviour { public float Speed; //定义速度 p ...
- 虚拟机扩容(/dev/mapper/centos-root 空间不足)
1:.首先查看我们的根分区大小是多少 df -h 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root xfs ...