题目链接:https://vjudge.net/problem/POJ-1228

题意:我是真的没看懂题意QAQ。。。搜了才知道。题目给了n个点,问这n个点确定的凸包是否能通过添加点来变成一个新的凸包。也就是这个凸包是否稳定,稳定输出YES,否则输出NO。

思路:
  首先给出结论,一个凸包稳定当且仅当它的每一条边上都有>=3个点。因为如果只有两个点的话,那么在这条边之外取一个点就能扩展出一个更大的凸包。而每条边上都有>=3个点时,此时扩展时会使得凸包变凹!

  所以我们需要改一下求凸包的模板,只用将while中的<=改成< 即可,但这不能将最后一条边上的多个点保留 ,因为排序时将距离近的点排在前面 ,那么最后一条边上的点仅有距离最远的会被保留,其余的会被出栈。所以最后一条边需要特判。(网上许多代码没有特判,仅仅只是在判断的时候忽略了最后一条边,然而数据弱,没有卡这个点,所以能AC)。

  求凸包之后需要判断每条边是不是由>=3个点。可以利用叉积判断点i处和点(i+1)处的夹角是否都不为0来判断,如果都不为0那么边(i , i+1)就不满足条件,因为前面特判了最后一条边(top , 0),所以这里枚举判断时就不用枚举最后一条边了。

AC code:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. using namespace std;
  6.  
  7. const int maxn=;
  8. const double PI=acos(-1.0);
  9.  
  10. struct Point{
  11. int x,y;
  12. Point():x(),y(){}
  13. Point(int x,int y):x(x),y(y){}
  14. }list[maxn];
  15. int stack[maxn],top,flag;
  16.  
  17. //计算叉积p0p1×p0p2
  18. int cross(Point p0,Point p1,Point p2){
  19. return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
  20. }
  21. //计算p1p2的距离
  22. double dis(Point p1,Point p2){
  23. return sqrt((double)(p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
  24. }
  25. //极角排序函数,角度相同则距离小的在前面
  26. bool cmp(Point p1,Point p2){
  27. int tmp=cross(list[],p1,p2);
  28. if(tmp>) return true;
  29. else if(tmp==&&dis(list[],p1)<dis(list[],p2)) return true;
  30. else return false;
  31. }
  32. //输入,把最左下角放在list[0],并且进行极角排序
  33. void init(int n){
  34. Point p0;
  35. scanf("%d%d",&list[].x,&list[].y);
  36. p0.x=list[].x;
  37. p0.y=list[].y;
  38. int k=;
  39. for(int i=;i<n;++i){
  40. scanf("%d%d",&list[i].x,&list[i].y);
  41. if((p0.y>list[i].y)||((p0.y==list[i].y)&&(p0.x>list[i].x))){
  42. p0.x=list[i].x;
  43. p0.y=list[i].y;
  44. k=i;
  45. }
  46. }
  47. list[k]=list[];
  48. list[]=p0;
  49. sort(list+,list+n,cmp);
  50. }
  51. //graham扫描法求凸包,凸包顶点存在stack栈中
  52. //从栈底到栈顶一次是逆时针方向排列的
  53. void graham(int n){
  54. if(n==){
  55. top=;
  56. stack[]=;
  57. return;
  58. }
  59. top=;
  60. stack[]=;
  61. stack[]=;
  62. for(int i=;i<n;++i){
  63. while(top>&&cross(list[stack[top-]],list[stack[top]],list[i])<) --top;
  64. stack[++top]=i;
  65. }
  66. if(cross(list[n-],list[n-],list[])!=) //特判最后一条边
  67. flag=;
  68. }
  69.  
  70. bool check(){
  71. for(int i=;i<top;++i){
  72. if(cross(list[stack[(i+top)%(top+)]],list[stack[i]],list[stack[(i+)%(top+)]])!=&&
  73. cross(list[stack[i]],list[stack[(i+)%(top+)]],list[stack[(i+)%(top+)]])!=)
  74. return false;
  75. }
  76. return true;
  77. }
  78.  
  79. int T,n;
  80.  
  81. int main(){
  82. scanf("%d",&T);
  83. while(T--){
  84. flag=;
  85. scanf("%d",&n);
  86. init(n);
  87. if(n<){
  88. printf("NO\n");
  89. continue;
  90. }
  91. graham(n);
  92. if(!flag){
  93. printf("NO\n");
  94. continue;
  95. }
  96. if(check()) printf("YES\n");
  97. else printf("NO\n");
  98. }
  99. return ;
  100. }

poj1228(稳定凸包+特判最后一条边)的更多相关文章

  1. poj1228稳定凸包

    就是给一系列点,看这是不是一个稳定凸包 稳定凸包是指一个凸包不能通过加点来使它扩大面积,也就是说每条边最少有三个点 判断的地方写错了,写了两边循环,其实数组s已经排好了序,直接每三个判断就好了 #in ...

  2. POJ1228(稳定凸包问题)

    题目:Grandpa's Estate   题意:输入一个凸包上的点(没有凸包内部的点,要么是凸包顶点,要么是凸包边上的点),判断这个凸包是否稳定.所谓稳 定就是判断能不能在原有凸包上加点,得到一个更 ...

  3. POJ1228 Grandpa's Estate 稳定凸包

    POJ1228 转自http://www.cnblogs.com/xdruid/archive/2012/06/20/2555536.html   这道题算是很好的一道凸包的题吧,做完后会加深对凸包的 ...

  4. POJ 1228 - Grandpa's Estate 稳定凸包

    稳定凸包问题 要求每条边上至少有三个点,且对凸包上点数为1,2时要特判 巨坑无比,调了很长时间= = //POJ 1228 //稳定凸包问题,等价于每条边上至少有三个点,但对m = 1(点)和m = ...

  5. Grandpa's Estate - POJ 1228(稳定凸包)

    刚开始看这个题目不知道是什么东东,后面看了大神的题解才知道是稳定凸包问题,什么是稳定凸包呢?所谓稳定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点.知道了这个东 ...

  6. poj 1228 稳定凸包

    Grandpa's Estate Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12337   Accepted: 3451 ...

  7. POJ 1228 (稳定凸包问题)

    <题目链接> <转载于  >>> > 首先来了解什么是稳定的凸包.比如有4个点: 这四个点是某个凸包上的部分点,他们连起来后确实还是一个凸包.但是原始的凸包可 ...

  8. 凸包稳定性判断:每条边上是否至少有三点 POJ 1228

    //凸包稳定性判断:每条边上是否至少有三点 // POJ 1228 #include <iostream> #include <cstdio> #include <cst ...

  9. Gym 101128J Saint John Festival(凸包 + 二分判点和凸包关系)题解

    题意:给你一堆黑点一堆红点,问你有最多几个黑点能找到三个红点,使这个黑点在三角形内? 思路:显然红点组成的凸包内的所有黑点都能做到.但是判断黑点和凸包的关系朴素方法使O(n^2),显然超时.那么我现在 ...

随机推荐

  1. css+vue实现流程图

    主要用css+flex布局实现样式部分,vue实现组件逻辑.首先看下效果吧: 当空间不够时还可以使用拖拽功能 接下来说明下实现思路 1.首先是实现单个节点样式,这个很简单不谈了,节点后都跟有一小段连接 ...

  2. 【CSP模拟赛】避难向导(倍增lca&树的直径)

    耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...

  3. reverse啥时候可以用

    在做历史搜索记录的时候,当你想把最新的数据放到前面,可以用到,其实就是一个数组的反转. let array=[ '周小姐','好可爱的' ] var box=array.reverse() conso ...

  4. window.location.href在微信端不起作用的解决方法?

    在我从第一张图的某个活动进去到详情页,点击返回是可以的,这里我是用了一个click事件,window.location.href="某死链接" 但是第二次进去点击之后点击事件是可以 ...

  5. css设置使文字显示2行多余的为省略号...

    1 2 3 4 5 6 7 8 9 10 11 12 .title{        font-size: .7rem;        line-height: 1.5rem;          ove ...

  6. 第06组 Alpha冲刺(2/6)

    队名:拾光组 组长博客链接 作业博客链接 团队项目情况 燃尽图(组内共享) 组长:宋奕 过去两天完成了哪些任务 主要完成了上传照片模块的信息采集 具体完成了采集用户上传的照片信息.分析图像数据.比对数 ...

  7. JWT签名算法

    JWT签名算法 JWT签名算法中,一般有两个选择,一个采用HS256,另外一个就是采用RS256. 签名实际上是一个加密的过程,生成一段标识(也是JWT的一部分)作为接收方验证信息是否被篡改的依据. ...

  8. JVM 初始化阶段的重要意义分析

    1.创建一个Mytest6类和Singleton类 public class MyTest6 { public static void main(String[] args) { Singleton ...

  9. LSTM和双向LSTM讲解及实践

    LSTM和双向LSTM讲解及实践 目录 RNN的长期依赖问题LSTM原理讲解双向LSTM原理讲解Keras实现LSTM和双向LSTM 一.RNN的长期依赖问题 在上篇文章中介绍的循环神经网络RNN在训 ...

  10. Numpy中ndim、shape、dtype、astype的用法

    本文链接:https://blog.csdn.net/Da_wan/article/details/80518725本文介绍numpy数组中这四个方法的区别ndim.shape.dtype.astyp ...