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

来源:互联网 发布:工频变压器设计软件 编辑:程序博客网 时间:2024/06/13 11:53

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
原创粉丝点击