求包括n个矩形的最小矩形面积模板
来源:互联网 发布:希尔巴布尔美全灭mac 编辑:程序博客网 时间:2024/05/17 23:30
typedef double typev;const double eps = 1e-8;const int N = 50005;int sign(double d){ return d < -eps ? -1 : (d > eps);}struct point{ typev x, y; point operator-(point d){ point dd; dd.x = this->x - d.x; dd.y = this->y - d.y; return dd; } point operator+(point d){ point dd; dd.x = this->x + d.x; dd.y = this->y + d.y; return dd; }}ps[N];//int n, cn;double dist(point d1, point d2){ return sqrt(pow(d1.x - d2.x, 2.0) + pow(d1.y - d2.y, 2.0));}double dist2(point d1, point d2){ return pow(d1.x - d2.x, 2.0) + pow(d1.y - d2.y, 2.0);}bool cmp(point d1, point d2){ return d1.y < d2.y || (d1.y == d2.y && d1.x < d2.x);}//st1-->ed1叉乘st2-->ed2的值typev xmul(point st1, point ed1, point st2, point ed2){ return (ed1.x - st1.x) * (ed2.y - st2.y) - (ed1.y - st1.y) * (ed2.x - st2.x);}typev dmul(point st1, point ed1, point st2, point ed2){ return (ed1.x - st1.x) * (ed2.x - st2.x) + (ed1.y - st1.y) * (ed2.y - st2.y);}//多边形类struct poly{ static const int N = 50005; //点数的最大值 point ps[N+5]; //逆时针存储多边形的点,[0,pn-1]存储点 int pn; //点数 poly() { pn = 0; } //加进一个点 void push(point tp){ ps[pn++] = tp; } //第k个位置 int trim(int k){ return (k+pn)%pn; } void clear(){ pn = 0; }};//返回含有n个点的点集ps的凸包poly graham(point* ps, int n){ sort(ps, ps + n, cmp); poly ans; if(n <= 2){ for(int i = 0; i < n; i++){ ans.push(ps[i]); } return ans; } ans.push(ps[0]); ans.push(ps[1]); point* tps = ans.ps; int top = -1; tps[++top] = ps[0]; tps[++top] = ps[1]; for(int i = 2; i < n; i++){ while(top > 0 && xmul(tps[top - 1], tps[top], tps[top - 1], ps[i]) <= 0) top--; tps[++top] = ps[i]; } int tmp = top; //注意要赋值给tmp! for(int i = n - 2; i >= 0; i--){ while(top > tmp && xmul(tps[top - 1], tps[top], tps[top - 1], ps[i]) <= 0) top--; tps[++top] = ps[i]; } ans.pn = top; return ans;}//求点p到st->ed的垂足,列参数方程point getRoot(point p, point st, point ed){ point ans; double u=((ed.x-st.x)*(ed.x-st.x)+(ed.y-st.y)*(ed.y-st.y)); u = ((ed.x-st.x)*(ed.x-p.x)+(ed.y-st.y)*(ed.y-p.y))/u; ans.x = u*st.x+(1-u)*ed.x; ans.y = u*st.y+(1-u)*ed.y; return ans;}//next为直线(st,ed)上的点,返回next沿(st,ed)右手垂直方向延伸l之后的点point change(point st, point ed, point next, double l){ point dd; dd.x = -(ed - st).y; dd.y = (ed - st).x; double len = sqrt(dd.x * dd.x + dd.y * dd.y); dd.x /= len, dd.y /= len; dd.x *= l, dd.y *= l; dd = dd + next; return dd;}//求含n个点的点集ps的最小面积矩形,并把结果放在ds(ds为一个长度是4的数组即可,ds中的点是逆时针的)中,并返回这个最小面积。double getMinAreaRect(point* ps, int n, point* ds){ int cn, i; double ans; point* con; poly tpoly = graham(ps, n); con = tpoly.ps; cn = tpoly.pn; if(cn <= 2){ ds[0] = con[0]; ds[1] = con[1]; ds[2] = con[1]; ds[3] = con[0]; ans=0; }else{ int l, r, u; double tmp, len; con[cn] = con[0]; ans = 1e40; l = i = 0; while(dmul(con[i], con[i+1], con[i], con[l]) >= dmul(con[i], con[i+1], con[i], con[(l-1+cn)%cn])){ l = (l-1+cn)%cn; } for(r=u=i = 0; i < cn; i++){ while(xmul(con[i], con[i+1], con[i], con[u]) <= xmul(con[i], con[i+1], con[i], con[(u+1)%cn])){ u = (u+1)%cn; } while(dmul(con[i], con[i+1], con[i], con[r]) <= dmul(con[i], con[i+1], con[i], con[(r+1)%cn])){ r = (r+1)%cn; } while(dmul(con[i], con[i+1], con[i], con[l]) >= dmul(con[i], con[i+1], con[i], con[(l+1)%cn])){ l = (l+1)%cn; } tmp = dmul(con[i], con[i+1], con[i], con[r]) - dmul(con[i], con[i+1], con[i], con[l]); tmp *= xmul(con[i], con[i+1], con[i], con[u]); tmp /= dist2(con[i], con[i+1]); len = xmul(con[i], con[i+1], con[i], con[u])/dist(con[i], con[i+1]); if(sign(tmp - ans) < 0){ ans = tmp; ds[0] = getRoot(con[l], con[i], con[i+1]); ds[1] = getRoot(con[r], con[i+1], con[i]); ds[2] = change(con[i], con[i+1], ds[1], len); ds[3] = change(con[i], con[i+1], ds[0], len); } } } return ans+eps;}
0 0
- 求包括n个矩形的最小矩形面积模板
- 求n个矩形面积——坐标离散化
- HDU 5251 矩形面积 (计算几何+旋转卡壳求覆盖凸包的最小矩形面积)
- Arithmetic problem | 求n个直方图所含最大的矩形面积
- 点的外接矩形最小周长和面积模板
- 求矩形交集的面积
- 求矩形交集的面积
- 求矩形并的面积
- 求矩形并的面积
- 求矩形并的面积(线段树)【模板】
- UVA 11345 Rectangles(n个矩形重叠覆盖的面积)
- 求最大矩形面积
- 矩形面积求并
- 求矩形相交面积
- 求矩形覆盖面积
- UVA10173(求凸包的面积最小外接矩形)
- hdu 5251 矩形面积 (旋转卡壳求最小面积外接矩形)
- 上机项目--求矩形的周长面积
- HDOJ 题目5289 Assignment(RMQ,技巧)
- Android实战简易教程-第二十八枪(Uri转String型实例)
- HTML5基础16----HTML5框架
- [基本实验] 远程文件包含
- CodeForces327C
- 求包括n个矩形的最小矩形面积模板
- 时间处理
- bootstrap javascript插件中类成员命名之最前面有无$
- 解决VS编译出现Moc'ing文件,系统找不到指定路径问题
- 引脚定义
- B+树索引(转)
- 1.1Qemu 用户态架构
- 求给定M个数组合构成N的最小倍数
- poj 1185 状态压缩dp(炮兵阵地)