POJ 2451 Uyuw's Concert 题解
2014-08-30 16:31
337 查看
半平面的模板题。
解释的比较好的:/article/1891120.html
可以参考的资源:http://download.csdn.net/detail/u011523796/7843357
解释的比较好的:/article/1891120.html
可以参考的资源:http://download.csdn.net/detail/u011523796/7843357
///article/1891120.html #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> using namespace std; const int N = 20009; const double eps = 1e-8; const double maxl = 70000; const double pi = acos(-1.0); struct cpoint {//C++构造函数,默认缺省值为(0,0) double x, y; cpoint(double xx = 0, double yy = 0): x(xx), y(yy) {}; }; int dcmp(double x) {//判断参数的符号,负数返回-1,0返回0,正数返回1 if (x < -eps) return -1; else return x > eps; } double xmult(cpoint p0, cpoint p1, cpoint p2) { // p0p1 与 p0p2 叉积 return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); } bool EqualPoint(cpoint a, cpoint b) {//两点相等 return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; } struct cvector {//向量 cpoint s, e; double ang, d; }; //atan (double x)弧度表示的反正切 //atan2(double x,double y)弧度表示的反正切,相当于atan(x/y) void setline(double x1, double y1, double x2, double y2, cvector &v) { v.s.x = x1; v.s.y = y1; v.e.x = x2; v.e.y = y2; v.ang = atan2(y2 - y1, x2 - x1); //这里的 d 代表向量(直线)和坐标轴的截距,正数表示 原点 在该向量的左边 //(这道题要求左半平面交),负号则表示 原点 在右边 if (dcmp(x1 - x2)) // x1 > x2 v.d = (x1 * y2 - x2 * y1) / fabs(x1 - x2); else v.d = (x1 * y2 - x2 * y1) / fabs(y1 - y2); } //判向量平行 bool parallel(const cvector &a, const cvector &b) { double u = (a.e.x - a.s.x) * (b.e.y - b.s.y) - (a.e.y - a.s.y) * (b.e.x - b.s.x); return dcmp(u) == 0; } //求两向量(直线)交点 (两向量不能平行或重合) cpoint CrossPoint(const cvector &a, const cvector &b) { cpoint res; double u = xmult(a.s, a.e, b.s), v = xmult(a.e, a.s, b.e); res.x = (b.s.x * v + b.e.x * u) / (u + v); res.y = (b.s.y * v + b.e.y * u) / (u + v); return res; } //半平面交排序函数 [优先顺序: 1.极角 2.前面的直线在后面的左边] static bool VecCmp(const cvector &l, const cvector &r) { if (dcmp(l.ang - r.ang)) return l.ang < r.ang; return l.d < r.d; } cvector deq ; //用于计算的双端队列 void HalfPanelCross(cvector vec[],int n,cpoint cp[],int &m) { int i,tn; sort(vec,vec+n,VecCmp); for(tn=i=1;i<n;i++)//去掉极角相同的边,同时留下最右边的 { if(dcmp(vec[i].ang-vec[i-1].ang) != 0) vec[tn++]=vec[i]; }n=tn; int bot=0, top=1; deq[0]=vec[0], deq[1]=vec[1]; for(i=2;i<tn;i++) { if(parallel(deq[top],deq[top-1]) || parallel(deq[bot],deq[bot+1]))return ; while(bot<top && dcmp(xmult(vec[i].s,vec[i].e,CrossPoint(deq[top],deq[top-1])))<0) top--;//处理下凸壳 while(bot<top && dcmp(xmult(vec[i].s,vec[i].e,CrossPoint(deq[bot],deq[bot+1])))<0) bot++;//处理上凸壳 deq[++top]=vec[i]; } while(bot<top && dcmp(xmult(deq[bot].s,deq[bot].e,CrossPoint(deq[top],deq[top-1])))<0) top--;//先滤除左侧的半平面。指针 p1 指向下凸壳的最左侧,p2 指向上凸壳的最左侧。 while(bot<top && dcmp(xmult(deq[top].s,deq[top].e,CrossPoint(deq[bot],deq[bot+1])))<0) bot++;//滤除右侧没有用的半平面 if(top <= bot+1)return ; for(m=0,i=bot;i<top;i++) cp[m++]=CrossPoint(deq[i],deq[i+1]); if(bot<top+1) cp[m++]=CrossPoint(deq[bot],deq[top]); m=unique(cp,cp+m,EqualPoint)-cp; } double PolygonArea(cpoint p[], int n) { if (n < 3) return 0; double s = p[0].y * (p[n - 1].x - p[1].x); for (int i = 1; i < n; ++i) s += p[i].y * (p[i - 1].x - p[(i + 1) % n].x); return fabs(s / 2); // 顺时针方向 s为负 } int n,m; cvector v ; cpoint cp ; void solve() { int i,j; setline(0, 0, 10000, 0, v[0]);//为了保证结果是凸多边形或其退化,首先建立一个非~常~大的边框 setline(10000, 0, 10000, 10000, v[1]); setline(10000, 10000, 0, 10000, v[2]); setline(0, 10000, 0, 0, v[3]); cpoint p ; double x1,y1,x2,y2; for(j=4,i=0;i<n;i++){ scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); setline(x1,y1,x2,y2,v[j++]); } n=j; HalfPanelCross(v,n,cp,m);//向量(直线)集合,长度;点集,长度 printf("%.1lf\n",PolygonArea(cp,m)); } int main() { while(~scanf("%d",&n)) { memset(cp,0,sizeof(cp)); memset(v,0,sizeof(v)); solve(); } return 0; }
相关文章推荐
- POJ 2451 Uyuw's Concert
- POJ 2451 Uyuw's Concert(半平面交nlgn)
- POJ 2451 Uyuw's Concert(半平面交)
- POJ 2451 Uyuw's Concert(半平面交求面积)
- POJ 2451 Uyuw's Concert
- poj 2451 Uyuw's Concert(半平面交求面积)
- POJ 2451 Uyuw's Concert
- POJ 2451 Uyuw's Concert 半平面交O(nlogn)
- poj 2451 Uyuw's Concert - 半平面交
- POJ 2451 Uyuw's Concert (半平面交)
- POJ 2451: Uyuw's Concert 半平面交
- POJ2451-Uyuw's Concert
- poj2451 Uyuw's Concert【半平面交】
- 【Poj 2451】Uyuw's Concert
- poj 2451 Uyuw's Concert
- POJ 2451 Uyuw's Concert 半平面交求面积
- POJ 2451 Uyuw's Concert(半平面交,求面积,裸)
- poj 2451 Uyuw's Concert (半平面交)
- POJ 2451 Uyuw's Concert
- poj1702——Eva's Balance