判断稳定凸包,求凸包代码(poj1228)

来源:互联网 发布:linux mplayer 缩小 编辑:程序博客网 时间:2024/06/06 02:43

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;const double eps = 1e-8;struct Point {    double x, y;} pnt[1005];int stk[1005], top;int dblcmp(double k) {    if (fabs(k) < eps) return 0;    return k > 0 ? 1 : -1;}double multi(Point p0, Point p1, Point p2) {    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}double getDis(Point a, Point b) {    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}bool cmp(const Point& a, const Point& b) {    int d = dblcmp(multi(pnt[0], a, b));    if (!d) return getDis(pnt[0], a) < getDis(pnt[0], b);    return d > 0;}int main(){    int t, n, i, k;    double tx, ty;    scanf ("%d", &t);    while (t--) {        scanf ("%d", &n);        //先要找到最左下角的点        scanf ("%lf%lf", &pnt[0].x, &pnt[0].y);        tx = pnt[0].x; ty = pnt[0].y;        k = 0;        for (i = 1; i < n; i++) {            scanf ("%lf%lf", &pnt[i].x, &pnt[i].y);            int d = dblcmp(ty-pnt[i].y);            if (d > 0) {                k = i;                tx = pnt[i].x;                ty = pnt[i].y;            }            else if (!d && dblcmp(tx-pnt[i].x) > 0) {                k = i;                tx = pnt[i].x;            }        }        pnt[k].x = pnt[0].x;        pnt[k].y = pnt[0].y;        pnt[0].x = tx;        pnt[0].y = ty;        //极角排序        sort(pnt+1, pnt+n, cmp);        //以下是求凸包的代码,stk数组中存的是凸包角上的点集        stk[0] = 0;        stk[1] = 1;        top = 1;        for (i = 2; i < n; i++) {            while (top >= 1 && dblcmp(multi(pnt[stk[top-1]], pnt[i], pnt[stk[top]])) >= 0) top--;            stk[++top] = i;        }                if (top <= 1) {            printf ("NO\n");            continue;        }        bool flag = false;        for (i = 1; i <= top; i++)            if (stk[i]-stk[i-1] == 1) {                flag = true;                break;            }        for (i = 1; i < n-1; i++)            if (!dblcmp(multi(pnt[0], pnt[i], pnt[n-1]))) break;//说明首尾连线之间至少有1个点        if (!flag && i < n-1) printf ("YES\n");        else printf ("NO\n");    }    return 0;}

题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1228

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

         得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。

         很容易得到,当一个凸包稳定时,凸包的每条边上都要有至少三个点,若只有两个点,则可以增加一个点,得到更大的凸包。

思路:直接求凸包,得到原来凸包顶点,去掉凸包边上的点,由于求凸包的过程中要对点集pnt[]极角排序,最后只需判断求得的凸包上的点在排序后的pnt[]中是否相邻,

         凸包中第一个和最后一个点还需特别判断一下它们之间是否有点,若求得凸包中的点个数为2,则输入的所有点都在一条线上,这时需输出NO



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 魅蓝5s发热严重怎么办 华为荣耀v8信号差怎么办 贴膜白边去除液漏进屏幕里面怎么办 魅族pro6s电池休眠了怎么办 京东预约错了怎么办 魅蓝手机声音小怎么办 魅族2手机锁定了怎么办 flyme的密码忘了怎么办 魅族note3忘记开机密码怎么办 小米3s手机死机怎么办 二手小米手机有账号锁怎么办 小米五指纹解锁失灵怎么办 小米note3指纹解锁失灵怎么办 小米4s手机屏幕失灵怎么办 vivo手机没有otg功能怎么办 头戴耳机压头发怎么办 小米4c很卡怎么办 小米4c玩王者怎么办 小米4s屏幕乱跳怎么办 小米4s手机后壳碎了怎么办 小米5spius开不了机怎么办 小米5s无限重启怎么办 小米5s外屏坏了怎么办 小米5s内屏碎了怎么办 小米4充电没反应怎么办 小米5手机变卡了怎么办 小米5变卡了怎么办 小米手机充电无反应怎么办 小米6相机卡顿怎么办 华为手机玩游戏发热怎么办 华为手机变慢了怎么办 华为p10手机变慢怎么办 华为手机账户密码忘记了怎么办 QQ浏览器无法加载插件怎么办 电脑开了机黑屏怎么办 扫描仪打不开运单扫描怎么办 打印机不支持64位系统怎么办 xp系统dnf闪退怎么办 w10电脑所有程序都打不开怎么办 安卓手机太卡怎么办 系统装到f盘了怎么办