POJ3130排序增量法
来源:互联网 发布:js对联广告 编辑:程序博客网 时间:2024/05/21 09:28
这是POJ3130的一段AC代码,使用zzy的排序增量法解决。算法流程完全按照http://blog.csdn.net/u012061345/article/details/23872929所述
#include <iostream>#include <algorithm>using namespace std; double const EPS = 1E-6; #define isZero(x) ( - EPS <= (x) && (x) <= EPS )#define isEq(x,y) isZero( (x) - (y) ) struct point_t{ int x; int y; point_t(int a=0,int b=0):x(a),y(b){}};struct point64f_t{ double x; double y; point64f_t(double a=0.0,double b=0.0):x(a),y(b){}};struct hp_t{ double a; double b; double c;//ax+by+c>=0,法向量始终是(a,b)};//根据法向量的极角排序(-180,180],极角相同,越靠近法向量的越小bool operator < (hp_t const&l,hp_t const&r){ //法向量分别位于x轴上下,可以直接得到结果 int ly = l.b >= 0 ? 1 : -1; int ry = r.b >= 0 ? 1 : -1; if ( ly != ry ) return ly < ry; //如果都位于x轴上 if ( isZero(l.b) && isZero(r.b) && l.a * r.a < 0 ) return l.a > r.a; double chaji = l.a * r.b - l.b * r.a; if ( !isZero(chaji) ) return chaji > 0; //法向量完全平行,当a为正时 if ( l.a > EPS ){ //若hp1比hp2更靠近法向量,则必有a1x+b1y+c1=0而a2x+b2y+c2>0 return l.c * r.a < l.a * r.c; } if ( l.a < - EPS )return l.c * r.a > l.a * r.c; //a如果为0,b必然不为0 if ( l.b > EPS ) return l.c * r.b < l.b * r.c; return l.c * r.b > l.b * r.c;}//判断半平面是否平行bool isPara(hp_t const&l,hp_t const&r){ int ly = l.b >= 0 ? 1 : -1; int ry = r.b >= 0 ? 1 : -1; if ( ly != ry ) return false; if ( isZero(l.b) && isZero(r.b) ) return l.a * r.a > 0; return isZero( l.a * r.b - r.a * l.b );}//从l到r,保证是逆时针方向,a、b是唯一确定的inline void genHP(point_t const&l,point_t const&r,hp_t&hp){ hp.a = (double)( l.y - r.y ); hp.b = (double)( r.x - l.x ); hp.c = (double)( l.x * r.y - l.y * r.x );}//半平面相交求交点,保证有且只有一个交点inline void inter(hp_t const&l,hp_t const&r,point64f_t&p){ double xishu = l.a * r.b - r.a * l.b; p.x = ( l.b * r.c - r.b * l.c ) / xishu; p.y = ( l.c * r.a - l.a * r.c ) / xishu;}//判断点是否在半平面内inline bool isIn(point64f_t const&p,hp_t const&hp){ double v = hp.a * p.x + hp.b * p.y + hp.c; return v >= - EPS;}//排序增量法,会改变hp里面的内容bool sandi(hp_t hp[],int n){ int bot = 0; int top = 1; for(int i=2;i<n;++i){ //最前端的两个半平面相交 while( bot < top ){ point64f_t p; inter(hp[top-1],hp[top],p); //p在当前半平面外,出队列 if ( isIn(p,hp[i]) ) break; else --top; } //最底端的两个半平面相交 while( bot < top ){ point64f_t p; inter(hp[bot],hp[bot+1],p); //p在当前半平面外,出队列 if ( isIn(p,hp[i]) ) break; else ++bot; } //赋值 hp[++top] = hp[i]; } //后处理 while( bot < top ){ point64f_t p; inter(hp[top-1],hp[top],p); //p在当前半平面外,出队列 if ( isIn(p,hp[bot]) ) break; else --top; } while( bot < top ){ point64f_t p; inter(hp[bot],hp[bot+1],p); //p在当前半平面外,出队列 if ( isIn(p,hp[top]) ) break; else ++bot; } return top - bot > 1;} point_t P[55];hp_t Hp[55];int main(){ int n; while( scanf("%d",&n) && n ){ for(int i=0;i<n;++i)scanf("%d%d",&P[i].x,&P[i].y); P[n] = P[0]; //生成半平面 for(int i=0;i<n;++i) genHP(P[i],P[i+1],Hp[i]); //排序 sort(Hp,Hp+n); //完全平行的半平面只取一个 hp_t* p = unique(Hp,Hp+n,isPara); //待处理的半平面个数 n = p - Hp; //S&I printf(sandi(Hp,n)?"1\n":"0\n"); } return 0;}
0 0
- POJ3130排序增量法
- 增量法-插入排序算法
- 半平面相交的排序增量法
- 希尔排序(增量排序)
- 增量排序(未)
- 希尔排序(缩小增量排序)
- 希尔排序 缩小增量排序
- 《算法导论》学习笔记No.1--插入排序 增量法
- 算法【3】:直接插入排序(又叫增量法)
- shell排序,希尔排序,递减增量排序。
- 排序 - 希尔排序(缩小增量排序)
- Java排序--》希尔排序(增量排序)
- 希尔排序(使用希尔增量)
- 希尔排序增量序列简介
- shell(缩小增量)排序
- Java 希尔排序(缩小增量排序)
- 希尔排序(缩小增量排序)
- 理解希尔排序,缩减增量排序
- C++ sort
- 设计模式(5)-对象创建型模式-Builder模式
- 使用strlcpy和strlcat
- 在win7下开启mysql服务
- Android Loaders(三)实现一个Base Loader
- POJ3130排序增量法
- asp获取当前路径语句大全
- nyoj 61 传纸条(一)双线程DP
- Asp.net课后生活(6)
- STM32F4 TIM1 7路PWM信号输出
- LeetCode: Linked List Cycle II
- Android中dip、dp、sp、pt和px的区别
- Asp.net课后总结(8)
- linux 下的select函数