UVA 10078 The Art Gallery(凸多边形判定)

558 篇文章 0 订阅
273 篇文章 0 订阅

UVA 10078 The Art Gallery(凸多边形判定)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1019

题意:

       给你一个多边形,按时针顺序(顺时针或逆时针)给出这个多边形的所有顶点,问你该多边形内是否存在临界点? 临界点就是当你站在多边形内的那点处,你想看到多边形内部的所有其他边时,视野会被挡住.

分析:

       其实临界点只有凹多边形才会有,凸多边形不可能存在临界点.所以本题直接转化为判断一个多边形是不是凸多边形的问题. 有下面两种方法解决:

1.    如果多边形是凸多边形,那么它所有的边都是往相同方向转的.假设现在有i边,i+1边,i+2边.所以i边与i+1边的叉积符号必然与i边与i+1边的叉积符号同号.如果i+1边在第i条边的基础上往左转,那么它们的向量叉积>0.否则<0. 如果它们共线,那么它们向量叉积==0.

2.    (由于题目给的点都是多边形的顶点)我们只要求该点集的凸包,看看凸包(最大点集)的大小是否==原始点集的大小即可. 如果不等,那么说明有些点不在凸包上,那么必然该多边形不是凸多边形.(当然对比面积也行)

AC代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

//精度控制
const double eps=1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}

//点
struct Point
{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
};

//向量
typedef Point Vector;

//点-点==向量
Vector operator-(Point A,Point B)
{
    return Vector(A.x-B.x,A.y-B.y);
}

//叉积
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}

//判断多边形是否是凸的
bool IsConvexPolygon(Point *p,int n)
{
    for(int i=0;i<n;i++)
    {
        double c1=Cross(p[(i+1)%n]-p[i], p[(i+2)%n]-p[(i+1)%n]);
        double c2=Cross(p[(i+2)%n]-p[(i+1)%n], p[(i+3)%n]-p[(i+2)%n]);
        if(dcmp(c1)*dcmp(c2)<0) return false;
    }
    return true;
}

const int maxn=50+5;
Point p[maxn];
int main()
{
    int n;
    while(scanf("%d",&n)==1 && n)
    {
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);

        printf("%s\n",IsConvexPolygon(p,n)?"No":"Yes");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值