POJ 1228 (稳定凸包问题)
来源:互联网 发布:大数据分析预测 知乎 编辑:程序博客网 时间:2024/06/05 22:46
转自:http://www.cnblogs.com/xdruid/archive/2012/06/20/2555536.html
这道题算是很好的一道凸包的题吧,做完后会加深对凸包的理解。
题意很关键。。。这英语看了好几遍才差不多看明白了。意思就是给你一堆点,这堆点本来就是某个凸包上的部分点,问你这堆点是否能确定唯一的凸包(大概这意思吧。。。)。后来搜了一下,发现这种凸包叫做稳定凸包。
首先来了解什么是稳定的凸包。比如有4个点:
这四个点是某个凸包上的部分点,他们连起来后确实还是一个凸包。但是原始的凸包可能不是这样。比如:
即这四个点构成的凸包不算做“稳定”的。我们发现,当凸包上存在一条边上的点只有端点两个点的时候,这个凸包不是稳定的,因为它可以在这条边外再引入一个点,构成一个新的凸包。但一旦一条边上存在三个点,那么不可能再找到一个点使它扩展成一个新的凸包,否则构成的新多边形将是凹的。
下面是一个典型的稳定凸包:
那么这道题的做法终于明确了。即求出给定这堆点的新的凸包,然后判断凸包上的每条边上是否至少有3个点存在,假如有一条边不符合条件,则输出NO。否则YES。
写的时候又遇到几个小问题了。。。一个是要修改一下凸包模板,大多数人的模板都是不包括共线点的。然后,如果输入的点数n小于6,那么直接输出NO。当然,也可以直接按极角排序进行比较。至于判断一条边上是否至少有三个点,我是这样做的,假设要判断的边i,那么判断边i和边i-1,边i和边i+1的夹角是否都为0(180)。
题意:输入一个凸包上的点(没有凸包内部的点,要么是凸包顶点,要么是凸包边上的点),判断这个凸包是否稳定。所谓稳
定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。
分析:容易知道,当一个凸包稳定时,凸包的每条边上都要有至少三个点,若只有两个点,则可以增加一个点,得到更大的凸
包。这样我们可以求出凸包,在求凸包时把共线的点也加进来,这样我们就判断是否有连续的三点共线即可,具体参见代码。
//POJ--1228#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#define eps 1e-8using namespace std;struct point{ double x,y;};point p[1010],stack[1010];int N,top;double multi(point p1, point p2, point p3) { return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);}double dis(point a, point b){ return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}int cmp(const void *a, const void *b){ point c = *(point *)a; point d = *(point *)b; double k = multi(p[0], c, d); if(k < 0 || (!k && dis(c, p[0]) > dis(d, p[0]))) return 1; return -1;}void Convex(){ for(int i = 1; i < N; i++) { point temp; if(p[i].y < p[0].y || ( p[i].y == p[0].y && p[i].x < p[0].x)) { temp = p[i]; p[i] = p[0]; p[0] = temp; } } qsort(p + 1, N - 1, sizeof(p[0]), cmp); stack[0] = p[0]; stack[1] = p[1]; top = 1; for(int i = 2; i < N; i++) { while(top >= 1 && multi(stack[top - 1], stack[top], p[i]) < 0) top--; //共线的点也压入凸包内; top++; stack[top] = p[i]; }}bool judge(){ for(int i=1;i<top;i++) { if((multi(stack[i-1],stack[i+1],stack[i]))!=0&&(multi(stack[i],stack[i+2],stack[i+1]))!=0) //判断每条边是否有至少三个点; return false; } return true;}int main(){ int t; cin>>t; while(t--) { cin>>N; for(int i=0;i<N;i++) scanf("%lf%lf",&p[i].x,&p[i].y); if(N<6) puts("NO"); else { Convex(); if(judge()) puts("YES"); else puts("NO"); } } return 0;}
- POJ 1228 稳定凸包问题
- POJ 1228 (稳定凸包问题)
- POJ 1228(稳定凸包)
- POJ 1228 稳定凸包
- POJ-1228(稳定凸包)
- poj 1228 求一个稳定凸包
- POJ 1873 & 1228 凸包和稳定凸包
- POJ1228(稳定凸包问题)
- POJ1228(稳定凸包问题)
- POJ 1228 Grandpa's Estate【稳定凸包判断】
- poj 1228 Grandpa's Estate[稳定凸包]
- POJ 1228 Grandpa's Estate (稳定凸包)
- POJ 1228 Grandpa's Estate(判断是否稳定凸包)
- POJ 1228:Grandpa's Estate (稳定凸包)
- POJ 1228 Grandpa's Estate(稳定凸包)
- POJ 1228 Grandpa's Estate(凸包应用:稳定凸包)
- POJ 1228 Grandpa's Estate(凸包应用:稳定凸包)
- POJ 1228 Grandpa's Estate (稳定凸包的判定)
- 一致性Hash算法的实现
- 科锐课堂笔记:2017/4/14 重载new、delete和引用计数
- 什么是css hack?
- Easy 1 Two Sum(1)
- 欢迎使用CSDN-markdown编辑器
- POJ 1228 (稳定凸包问题)
- 动态规划之最长公共子序列(LCS)
- STM32外部中断
- 实验吧——WriteUp&&涨姿势(1)
- js小案类
- 随机数
- Dubbo学习(一)入门
- springMVC利用WebArgumentResolver为controller注入当前用户对象参数
- JSP脚本标识