HDU 2907 Diamond Dealer(凸包对比)

来源:互联网 发布:js校验文本框输入数字 编辑:程序博客网 时间:2024/06/06 08:35

HDU 2907 Diamond Dealer(凸包对比)

http://acm.hdu.edu.cn/showproblem.php?pid=2907

题意:

       给你一个多边形(可能为凹的),然后要你求该多边形有多少个凹痕(一个凹痕内可能有多个凹角)和凹边.凹边就是构成凹角的边. 原始节点相邻3点不共线.


分析:

       首先求出凸包,得到逆时针排序的凸包上的点.

       由于原始节点是顺时针排序的,所以逆转原始节点数组.

       然后依次对比凸包上的相邻两点,看看凸包上相邻两点在原始节点数组中是否还存在点.

       如果存在,那么这就是一个凹角. 假设凸包上相邻两点间存在x个点是不在凸包上的原始节点,那么这个凹角由x+1条凹边构成.

       最终换算一下结果输出即可.

注意:这里是凹痕!!凹角是大于180的角,凹痕是有几个连续凹角组成的那个坑,这个需要重点理解一下,WA了无数次!

#include<iostream>#include<cmath>#include<algorithm>#include<cstdio>#include<cstring>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){}    bool operator==(const Point &rhs)const    {        return dcmp(x-rhs.x)==0 && dcmp(y-rhs.y)==0;    }    bool operator<(const Point &rhs)const    {        return dcmp(x-rhs.x)<0 || (dcmp(x-rhs.x)==0 && dcmp(y-rhs.x)<0);    }};//相邻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;}//求凸包int ConvexHull(Point *p,int n,Point *ch){    sort(p,p+n);    n=unique(p,p+n)-p;    int m=0;    for(int i=0;i<n;i++)    {        while(m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;        ch[m++]=p[i];    }    int k=m;    for(int i=n-2;i>=0;i--)    {        while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;        ch[m++]=p[i];    }    if(n>1) m--;    return m;}/***以上为刘汝佳模板***/const int maxn=500+5;Point P[maxn];Point p[maxn],q[maxn];int ansn,ansm;void check(int n,int num){int i,j;for(j=0;j<n;j++)if(q[j]==P[0])break;int ans=0;for(i=0;i<num;i++){ans=0;j=(j+1)%n;while(!(q[j]==P[(i+1)%num])){j=(j+1)%n;ans++;}if(ans>=1){ansm+=(ans+1);ansn++;}}}int main(){    int n,m,k;    int t;    scanf("%d",&t);    while(t--)    {    scanf("%d%d%d",&n,&m,&k);    for(int i=0;i<k;i++){scanf("%lf%lf",&p[i].x,&p[i].y);q[i].x=p[i].x;q[i].y=p[i].y;}int num=ConvexHull(p,k,P);ansm=ansn=0;reverse(q,q+k);check(k,num);int ans=-ansn*n+(k-ansm)*m;if(ans<0)ans=0;printf("%d\n",ans);    }    return 0;}


原创粉丝点击