POJ 1228 稳定凸包
2015-05-20 20:46
316 查看
题意:给出n个点,这n个点在凸包的边上或者点上。问仅由这 几个点能否确定凸包的形状。。
思路:考虑什么情况下不能是稳定的凸包,就是某个边上只有两个点,然后再往外面扩一个就可以形成一个新的凸包,如果边上还有一个点的话, 那么就不能添加新的点,因为给出的点是保证在凸包上的。。
凸包的模板跟之前的一题有点区别,就是对于共线的点是否加入凸包,正常的时候是不加入的(因为如果没什么要求的话加进去也没有用。。),但是这次需要判断中间是否有点,所以就加进去了(其实是别的题解加进去了2333),然后最后一条边上的点没有被加进,这不是因为求凸包的算法执行的时候的原因,是因为排序的原因,当最后一条线经过多个点的时候,会先连接距离近的点,所以找远的点的时候就会不满足左旋,把当前点弹出去。。
对于这道题的判断条件,就是那个judge函数,返回false的情况就是i-1,i,i+1,i+2形成了三条折线,这样i和i+1之间就没有点了,就不满足退出= =
代码:
思路:考虑什么情况下不能是稳定的凸包,就是某个边上只有两个点,然后再往外面扩一个就可以形成一个新的凸包,如果边上还有一个点的话, 那么就不能添加新的点,因为给出的点是保证在凸包上的。。
凸包的模板跟之前的一题有点区别,就是对于共线的点是否加入凸包,正常的时候是不加入的(因为如果没什么要求的话加进去也没有用。。),但是这次需要判断中间是否有点,所以就加进去了(其实是别的题解加进去了2333),然后最后一条边上的点没有被加进,这不是因为求凸包的算法执行的时候的原因,是因为排序的原因,当最后一条线经过多个点的时候,会先连接距离近的点,所以找远的点的时候就会不满足左旋,把当前点弹出去。。
对于这道题的判断条件,就是那个judge函数,返回false的情况就是i-1,i,i+1,i+2形成了三条折线,这样i和i+1之间就没有点了,就不满足退出= =
代码:
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<queue> #include<list> using namespace std; const double INF = 1e200; const double EP = 1e-10; const int maxn = 1100; const double PI = acos(-1); struct POINT{///点 定义 double x; double y; POINT(double a = 0,double b = 0){x = a;y = b;} }; struct SEGMENT{///line segment///线段 定义 POINT s; POINT e; SEGMENT(POINT a,POINT b){s = a;e = b;} SEGMENT(){} }; struct LINE{///ax + by + c = 0&&a >= 0///一般式 double a; double b; double c; LINE(double da,double db,double dc){a = da;b = db;c = dc;} LINE(double x1,double y1,double x2,double y2){///根据两个点求出一般式 a = y1 - y2;b = x2 - x1;c = x1*y2 - x2*y1; if(a < 0){a*=-1;b*=-1;c*=-1;} } }; double multiply(POINT sp,POINT ep,POINT op){///向量op->sp X op->ep的叉乘,小于0:ep在op->sp顺时针方向//大于0:ep在op->sp逆时针方向//等于0:三点共线 return ((sp.x - op.x)*(ep.y - op.y) - (ep.x - op.x)*(sp.y - op.y)); } double dotmultiply(POINT p1,POINT p2,POINT p0){ return ((p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y)); } bool online(SEGMENT l,POINT p){///判断点是否在线段上 return ((multiply(l.e,p,l.s) == 0)&&(((p.x-l.s.x)*(p.x-l.e.x))<= 0)&&(((p.y-l.s.y)*(p.y-l.e.y)) <= 0)); } bool intersect(SEGMENT u,SEGMENT v){///两线段相交(包括端点),返回true return ((max(u.s.x,u.e.x) >= min(v.s.x,v.e.x))&& (max(v.s.x,v.e.x) >= min(u.s.x,u.e.x))&& (max(u.s.y,u.e.y) >= min(v.s.y,v.e.y))&& (max(v.s.y,v.e.y) >= min(u.s.y,u.e.y))&& (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s) >= -EP)&& (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s) >= -EP)); } bool intersect_a(SEGMENT u,SEGMENT v){///两线段相交(不包括端点) return ((intersect(u,v))&& !online(u,v.s)&& !online(u,v.e)&& !online(v,u.e)&& !online(v,u.s)); } int lineintersect(LINE l1,LINE l2,POINT &p){///求两直线交点,有交点返回1和交点,没有返回0,重合返回2 double d = l1.a*l2.b-l2.a*l1.b; double d2 = l1.a*l2.c-l2.a*l1.c; double d3 = l1.b*l2.c-l2.b*l1.c; if(fabs(d) < EP&&fabs(d2) < EP&&fabs(d3) < EP)return 2; p.x = (l2.c*l1.b-l1.c*l2.b)/d; p.y = (l2.a*l1.c-l1.a*l2.c)/d; if(fabs(d) < EP)return 0; return 1; } 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 top;///凸包的顶点个数 POINT p[maxn],stack[maxn]; bool top_cmp(POINT a,POINT b){ double k = multiply(a,b,p[0]); if(k > 0)return 1; if(k < 0)return 0; return dis(a,p[0]) < dis(b,p[0]); } void graham(int n){ top = 1; int k = 0; for(int i = 1;i < n;i ++) if(p[i].y < p[k].y||((p[i].y == p[k].y)&&(p[i].x < p[k].x))) k=i; swap(p[0],p[k]); sort(p+1,p+n,top_cmp); stack[0] = p[0],stack[1] = p[1]; for(int i = 2;i < n;i ++){ while(top >= 1&&multiply(p[i],stack[top],stack[top-1]) > 0)top --; stack[++top] = p[i]; } } ///******************凸包结束**************** ///********************************************************************************* bool judge(){ for(int i = 1;i < top;i ++){ if(multiply(stack[i-1],stack[i+1],stack[i])&&multiply(stack[i],stack[i+2],stack[i+1]))return false; } return true; } int main(){ //freopen("in.txt","r",stdin); int T;//stack cin>>T; while(T --){ int n; cin>>n; for(int i = 0;i < n;i ++){ int a,b; cin>>a>>b; p[i].x = a; p[i].y = b; } if(n < 6){ puts("NO"); continue; } graham(n); if(judge())puts("YES"); else puts("NO"); } return 0; }
相关文章推荐
- POJ-1228(稳定凸包)
- poj 1228 求一个稳定凸包
- POJ 1228 Grandpa's Estate【稳定凸包判断】
- POJ 1228 Grandpa's Estate(判断是否稳定凸包)
- POJ 1228 (稳定凸包问题)
- POJ 1873 & 1228 凸包和稳定凸包
- Grandpa's Estate - POJ 1228(稳定凸包)
- poj 1228(稳定凸包)
- poj 1228 Grandpa's Estate (稳定凸包问题)
- POJ 1228(稳定凸包)
- POJ 1228 Grandpa's Estate(凸包应用:稳定凸包)
- POJ 1228 Grandpa's Estate (求稳定凸包)
- POJ 1228 —— “稳定”凸包
- POJ 1228 稳定凸包
- poj 1228 稳定凸包
- POJ1228(稳定凸包问题)
- POJ 1228 Grandpa's Estate(稳定凸包)
- POJ 1228:Grandpa's Estate (稳定凸包)
- poj 1228 Grandpa's Estate[稳定凸包]
- POJ 1228 稳定凸包问题