描述

矮人们平时有走亲访友的习惯。一天,矮人国要修一条高速公路,矮人们希望他们走亲访友的时候,能够不必穿越高速公路,这样会更安全一些。现在有M个高速公路的修建方案,请你判断这M条高速功能是否能满足矮人们的期望。也就是说给出平面上的N个点(矮人们的住所位置),对于M条直线(高速公路),依次判断这N个点是否在每条直线的同一侧。是输出GOOD,不是输出BAD。

后来从刘汝佳的书里发现这个算法叫旋转卡壳,专门求对踵点的。


题解

首先可以想出一个凸包模型来,因为求出所有点的凸包后可以判断直线如果穿过凸包,就一定不满足题意。
问题是怎么判断直线是否穿过凸包呢?

如果直线穿过凸包,就一定在凸包两个最远点的中间,最远点可以通过下面的方法找:首先预处理记录下凸包每个边的斜率,再算出直线的斜率,将斜率从小到大排列,假设直线斜率是正的,二分查找第一个大于直线斜率的边,它的起点一定是一个最远点,可以画图验证一下,因为他后面的边斜率比它大,也就相当于走的离凸包中心越来越近。然后把斜率取相反数,再找第一个斜率大于它的边,起点是另一个最远点。

在实现时直接用atan2()函数计算角度不用算斜率。


代码:

总时间耗费: 808ms
总内存耗费: 4 MB

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;const int maxn = 100000 + 10;
const double PI = acos(double(-1));int n;struct Point {double x, y;Point(double x=0, double y=0):x(x),y(y) {}
}p[maxn], ch[maxn];typedef Point Vector;Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }bool operator < (const Vector& a, const Vector& b) {return a.x < b.x || (a.x == b.x && a.y < b.y);
}const double eps = 1e-10;
int dcmp(double x) {if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}bool dcmp2(const double& a, const double& b) {if(dcmp(b-a) == 1) return 1;return 0;
}bool operator == (const Vector& a, const Vector& b) { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
}double angle(Vector v) { double ret = atan2(v.y, v.x); return ret < -PI/2 ? ret+2*PI : ret; }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }int ConvexHull() {sort(p, p+n);int m = 0;for(int i = 0; i < n; i++) {while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;ch[m++] = p[i];}int k = m;for(int i = n-2; i >= 0; i--) {while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;ch[m++] = p[i];}if(n > 1) m--;return m;
}double ang[maxn];int main() {scanf("%d", &n);for(int i = 0; i < n; i++) scanf("%lf%lf", &p[i].x, &p[i].y);int c = ConvexHull();for(int i = 0; i < c; i++) ang[i] = angle(ch[i+1]-ch[i]);Point a, b;while(scanf("%lf%lf%lf%lf", &a.x, &a.y, &b.x, &b.y) == 4) {if(n <= 1) printf("GOOD\n"); else {Point u = ch[upper_bound(ang, ang+c, angle(b-a), dcmp2)-ang];Point v = ch[upper_bound(ang, ang+c, angle(a-b), dcmp2)-ang];if(dcmp(Cross(b-a, u-a)*Cross(b-a, v-a)) < eps) printf("BAD\n");else printf("GOOD\n");}}return 0;
}

[codevs 1302] 小矮人(2002年CEOI中欧信息学奥赛)相关推荐

  1. 浅析拯救小矮人的 nlogn 算法及其证明

    浅析拯救小矮人的 nlogn 算法及其证明 题型简介: 有 $ n $ 个人,第 $ i $ 个人身高 $ a_i $ 手长 $ b_i $ ,他们为了从一个高为 $ H $ 的洞中出去,决定搭人梯. ...

  2. [TJOI2013]拯救小矮人(反悔贪心证明),「ICPC World Finals 2019」Hobson 的火车(基环树,差分)

    2021-09-07 test [TJOI2013]拯救小矮人 「ICPC World Finals 2019」Hobson 的火车 [TJOI2013]拯救小矮人 luogu4823 考试题目的数据 ...

  3. 洛谷 P4823 [TJOI2013]拯救小矮人

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于每一个小矮人,我们知道他从 ...

  4. 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...

  5. 使用canvas实现小矮人行走案例

    html代码 <canvas width="500" height="500"></canvas> <script src=&qu ...

  6. 项目管理小故事之小矮人的故事

    小矮人的故事 在古希腊时期的塞浦路斯,曾经有一座城堡里关着一群小矮人.传说他们是因为受到了可怕咒语的诅咒,而被关到这个与世隔绝的地方.他们找不到任何人可以求助,没有粮食,没有水,七个小矮人越来越绝 望 ...

  7. 《讲个故事》七个小矮人 与 七层模型

    某天深夜,标准委员会的工程师们的在酒吧里喝酒划拳,酒过三巡,越玩越嗨,谈到迪士尼电影的时候,他们把电影里7个小矮人的名字写在餐巾纸上,有个人开玩笑说 7 对于网络分层是个好数字.第二天上午在标准化委员 ...

  8. 《讲个故事》七个小矮人与OSI七层模型

    某天深夜,标准委员会的工程师们的在酒吧里喝酒划拳,酒过三巡,越玩越嗨,谈到迪士尼电影的时候,他们把电影里7个小矮人的名字写在餐巾纸上,有个人开玩笑说 7 对于网络分层是个好数字.第二天上午在标准化委员 ...

  9. 【BZOJ3174】【codevs25442075】拯救小矮人,DP+贪心

    Time:2016.07.19 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 传送门3 思路: 比较神的DP "贪心确定DP的状态"--reflash 写了 ...

最新文章

  1. No module named #39tensorflow.contrib#39
  2. [转]技巧:Vim 的纵向编辑模式
  3. ARM Linux 如何--注册和触发--软中断
  4. epoll socket 服务端中read和write的返回值讨论
  5. php asp 语法,ASP 语法
  6. JAVA-初步认识-第十三章-多线程(验证同步函数的锁)
  7. java中start与loop_java for-loop问题
  8. 系统图标及其注册表项
  9. Oracle exp/imp导入不同的表空间
  10. [AGC003F] Fraction of Fractal 矩阵快速幂
  11. android 快速启动 hibernate,什么是快速启动以及如何在Windows中启用或禁用它 | MOS86...
  12. baymax平台导入任务错误日志报错: Please login with USER and PASS.
  13. 图网络深度解析:为什么说图网络是 AI 的未来?
  14. java小球下落_java基础-小球下落问题
  15. windows RDP远程连接卡死问题
  16. 蓝天热键驱动_创建快捷方式或热键以立即弹出特定的USB驱动器
  17. Kibana常用搜索语法
  18. 怎么的测试用例是一个好的测试用例?
  19. Unity3D优化总结
  20. uboot.lds 链接文件分析

热门文章

  1. [云炬创业基础]创业过程
  2. 系统间通信2:通信管理与远程方法调用RMI
  3. openCV视频处理与图像转换
  4. FIR数字滤波器设计频率抽样法MATLAB仿真
  5. 批处理之显示隐藏文件
  6. c语言函数用指针传递参数问题
  7. js在IE下面弹出打开和保存文件的对话框
  8. javascript typeof的用法
  9. P7 计算机的性能指标
  10. 电路交换网络中,每条电路独占其经过的物理链路。