[XJOI NOI02015训练题7] B 线线线 【二分】
题目分析
题意:过一个点 P 的所有直线,与点集 Q 的最小距离是多少?一条直线与点集的距离定义为点集中每个点与直线距离的最大值。
题解:二分答案,对于一个二分的距离,我们可以求出对于每个点的可用的极角范围,然后判断 n 个点的极角范围有没有交即可。
听起来非常简单..结果我发现细节很麻烦..
因为,极角的范围是环形的,如果限定在 [-PI, PI] 的范围内,跨越 -PI = PI 这条线的极角范围就很难处理。
然后两个环上的范围的交可能是两段,也是很难处理..
学习神犇的处理方式,对于每个极角范围,在左端点记上一个 1,右端点记上一个 -1,然后如果一个位置被 n 个区间包含,那么这个位置的前缀和就是 n 。
非常的和谐,看起来问题已经解决了...然而我发现神犇的做法还是有些细节无法理解..
比如区间的范围可能超出了 [-PI, PI] ....但是我已经想不清楚了...还是记住这种处理方式吧
照着神犇的代码写之后还是 TLE 了 2 个点,最后改了改 Eps 让二分次数减少了一些,终于过了。
并且向下保留 3 位小数,我这样写 printf("%.3f\n", Ans - 0.0005); 就会 WA 掉 1 个点。
这样写 AnsN = (int)(Ans * 1000); printf("%d.%03d\n", AnsN / 1000, AnsN % 1000); 才能 AC。
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm> using namespace std; #define Vector Point
#define PI 3.14159265358979 inline void Read_Int(int &Num)
{
char c = getchar();
bool Neg = false;
while (c < '0' || c > '9')
{
if (c == '-') Neg = true;
c = getchar();
}
Num = c - '0'; c = getchar();
while (c >= '0' && c <= '9')
{
Num = Num * 10 + c - '0';
c = getchar();
}
if (Neg) Num = -Num;
} typedef double LF; inline LF gmin(LF a, LF b) {return a < b ? a : b;}
inline LF gmax(LF a, LF b) {return a > b ? a : b;}
inline LF Sqr(LF x) {return x * x;} const LF Eps = 1e-6; const int MaxN = 111111 + 5; int n, Top, Tot; LF dis[MaxN], ta[MaxN]; struct ES
{
LF Pos;
int Num;
ES() {}
ES(LF a, int b) {Pos = a; Num = b;}
} EQ[MaxN * 4]; inline bool Cmp(ES e1, ES e2)
{
return e1.Pos < e2.Pos;
} struct Point
{
LF x, y;
Point() {}
Point(LF a, LF b) {x = a; y = b;} void Read()
{
int a, b;
Read_Int(a); Read_Int(b);
x = (LF)a; y = (LF)b;
}
} Px, P[MaxN]; inline LF Dis(Point p1, Point p2)
{
return sqrt(Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y));
} bool Check(LF d)
{
LF l, r, t;
Top = 0; Tot = n;
for (int i = 1; i <= n; ++i)
{
if (dis[i] <= d)
{
--Tot;
continue;
}
t = asin(d / dis[i]);
l = ta[i] - t;
r = ta[i] + t;
EQ[++Top] = ES(l, 1);
EQ[++Top] = ES(r, -1);
if (ta[i] > 0)
{
EQ[++Top] = ES(l - PI, 1);
EQ[++Top] = ES(r - PI, -1);
}
else
{
EQ[++Top] = ES(l + PI, 1);
EQ[++Top] = ES(r + PI, -1);
}
}
if (Top == 0) return true;
int Cnt = 0;
sort(EQ + 1, EQ + Top + 1, Cmp);
for (int i = 1; i <= Top; ++i)
{
Cnt += EQ[i].Num;
if (Cnt == Tot) return true;
}
return false;
} int main()
{
scanf("%d", &n);
Px.Read();
for (int i = 1; i <= n; ++i)
{
P[i].Read();
dis[i] = Dis(P[i], Px);
ta[i] = atan2(P[i].y - Px.y, P[i].x - Px.x);
}
LF l, r, mid, Ans;
l = 0; r = 2000000;
while (r - l >= Eps)
{
mid = (l + r) / 2.0;
if (Check(mid))
{
Ans = mid;
r = mid - Eps;
}
else l = mid + Eps;
}
int AnsN = (int)(Ans * 1000);
printf("%d.%03d\n", AnsN / 1000, AnsN % 1000);
return 0;
}
[XJOI NOI02015训练题7] B 线线线 【二分】的更多相关文章
- X-NUCA 2017 web专题赛训练题 阳光总在风雨后和default wp
0X0.前言 X-NUCA 2017来了,想起2016 web专题赛,题目都打不开,希望这次主办方能够搞好点吧!还没开赛,依照惯例会有赛前指导,放一些训练题让CTFer们好感受一下题目. 题目有一大 ...
- PAT乙级真题及训练题 1025. 反转链表 (25)
PAT乙级真题及训练题 1025. 反转链表 (25) 感觉几个世纪没打代码了,真是坏习惯,调了两小时把反转链表调出来了,心情舒畅. 这道题的步骤 数据输入,数组纪录下一结点及储存值 创建链表并储存上 ...
- 9.19[XJOI] NOIP训练37
上午[XJOI] NOIP训练37 T1 同余方程 Problem description 已知一个整数a,素数p,求解 $x^{2}\equiv a(mod p) $ 是否有整数解 Solution ...
- 日常 java+雅思+训练题1
今天主要学了一些类似c中的一些语句,java也是一样类似的,只有一些点需要稍微注意一下,一些语句是新增的需要知道. 完完全全新学的知识就是class和instance的区别.如何创建实例.数据的封装. ...
- 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)
[LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...
- 中南大学2019年ACM寒假集训前期训练题集(基础题)
先写一部分,持续到更新完. A: 寒衣调 Description 男从戎,女守家.一夜,狼烟四起,男战死沙场.从此一道黄泉,两地离别.最后,女终于在等待中老去逝去.逝去的最后是换尽一生等到的相逢和团圆 ...
- 2019牛客多校第二场H题(悬线法)
把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...
- java基础集合经典训练题
第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...
- 2016huas暑假集训训练题 G-Who's in the Middle
题目链接:http://acm.hust.edu.cn/vjudge/contest/121192#problem/G 此题大意是给定一个数n 然后有n个数 要求求出其中位数 刚开始以为是按数学中的 ...
随机推荐
- monkeyrunner工具同Monkey工具的差别
Monkey: Monkey工具直接运行在设备或模拟器的adb shell中,生成用户或系统的伪随机事件流. monkeyrunner: monkeyrunner工具则是在工作站上通过API定义的特定 ...
- dede版权信息修改
login:dede-templets-login.htm 系统主页:dede-templets-index2.htm 主体内容在index_body.htm文件 干掉: $(function() ...
- ASP实现随机提取数据库记录例
<% "一个从数据库中随机读取纪录的例子 Set Rs1=server.CreateObject ("adodb.recordset") Set Rs=server ...
- openvswitch安装和使用 --修订通用教程的一些错误
1.下载openvswitch源文件,注意版本要适合操作系统内核. 推荐openvswitch2.0及其以上版本. 2.开始安装openvswitch cd openvswitch sudo ./bo ...
- UDP 多播 Java
1.服务端 public class UdpMulticastServer { /** * @param args */ public static void main(String[] args) ...
- ###学习《C++ Primer》- 2
点击查看Evernote原文. #@author: gr #@date: 2014-10-01 #@email: forgerui@gmail.com Part 2: STL顺序容器(第9章) 一.标 ...
- cocos2d-x实战 C++卷 学习笔记--第5章 精灵
前言: 精灵类是Sprite类.它的子类有PhysicsSprite 和 Skin. PhysicsSprite 是物理引擎精灵类,而Skin是皮肤精灵类,用于骨骼动画. 创建Sprite精灵对象 创 ...
- 利用css3动画和border来实现圆形进度条
最近在学习前端的一些知识,发现border的功能十分强大啊! 首先来看看demo 就是这么一个圆形的进度条,在文本框中输入0-100的数值下面的进度条相应的转到多少 这个主要是利用border,旋转和 ...
- 21_resultMap和resultType总结
[resultType] [ 作用 ] 将查询结果按照SQL列名与pojo属性名一致性 映射到pojo中. [ 使用场合 ] 常见的一些明细记录的展示,比如用户购买商品的明细,将关联查询信息全部展示在 ...
- 划分分区GPT11
umount /dev/sda1 /data1umount /dev/sdb1 /data2mount /dev/sdb1 /data1umount /dev/sdb2 /data3umount /d ...