hdu 4667(凸包)
2016-05-18 16:24
281 查看
题意:给出n个圆和m个三角形,把所有的图形围起来的最小长度。
分析:本题正解是求一堆切线,但是本题数据水,所以,把圆分成1000个点求凸包就好了,但是求长度的时候,在圆上的点要求圆弧长度。
代码如下:
分析:本题正解是求一堆切线,但是本题数据水,所以,把圆分成1000个点求凸包就好了,但是求长度的时候,在圆上的点要求圆弧长度。
代码如下:
<span style="font-family:FangSong_GB2312;font-size:18px;">#include <map> #include <set> #include <vector> #include <math.h> #include <string> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <functional> using namespace std; const int MAXN=100005; const double eps=1e-10; const double pi=acos(-1.0); int dcmp(double x){ if(fabs(x)<eps)return 0; if(x>0)return 1; return -1; } //因为精度的问题,在这里求减法的精度 struct Point { double x,y; int id; //所在的图形 }p[MAXN]; //几何图形中的点集 double dot(Point a,Point b,Point c){ double s1=b.x-a.x; double t1=b.y-a.y; double s2=c.x-a.x; double t2=c.y-a.y; return s1*s2+t1*t2; } //求解点积 int n,res[MAXN],top; bool cmp(Point a,Point b){ if(a.y==b.y)return a.x<b.x; return a.y<b.y; } //凸包的排序 bool mult(Point sp,Point ep,Point op){ return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y); } //凸包中的判断 void Graham(){ int len; top=1; sort(p,p+n,cmp); if(n==0)return;res[0]=0; if(n==1)return;res[1]=1; if(n==2)return;res[2]=2; for(int i=2;i<n;i++){ while(top&&mult(p[i],p[res[top]],p[res[top-1]]))top--; res[++top]=i; } len=top; res[++top]=n-2; for(int i=n-3;i>=0;i--){ while(top!=len&&mult(p[i],p[res[top]],p[res[top-1]]))top--; res[++top]=i; } } //求解凸包 double dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } //两点间距离 double R[1000]; int main() { int x,m; while(scanf("%d%d",&x,&m)!=EOF){ n=0; double x1,y1,r; for(int i=0;i<x;i++){ scanf("%lf%lf%lf",&x1,&y1,&r); R[i]=r; for(int j=0;j<1000;j++){ double tmp=2*pi*j/1000; //分解圆 p .id=i; p .x=x1+r*cos(tmp); p[n++].y=y1+r*sin(tmp); } } while(m--){ for(int i=1;i<=6;i++){ scanf("%lf",&r); if(i&1)p .x=r; else{ p .id=n; p[n++].y=r; } } } Graham(); double ans=0; for(int i=0;i<top;i++){ int t1=p[res[i]].id; int t2=p[res[(i+1)%top]].id; if(t1==t2){ ans+=pi*2*R[t1]/1000; } else ans+=dis(p[res[i]],p[res[(i+1)%top]]); //求和 } printf("%.4lf\n",ans); } return 0; }</span>
相关文章推荐
- 初学算法 - 求凸包的Garham's Scan算法的C++实现
- BZOJ2829信用卡凸包
- 凸包问题 hdu1392 Surround the Trees
- 【计算几何】POJ 1113
- [BZOJ1069][SCOI2007][凸包][旋转卡壳]最大土地面积
- 两个while循环求凸包 poj2187 poj1113
- [SHTSC 2012] 信用卡凸包
- codevs 1298 凸包周长
- POJ2187-最远点对->旋转卡壳(怎么开心怎么读)
- UVA10652【凸包计算】
- bzoj1007[HNOI2008]水平可见直线
- bzoj-2300 防线修建
- 例题4.6 包装木板 UVa10652
- 例题4.7 飞机场 UVa11168
- 【SDOI2014】【BZOJ3533】向量集
- HDU 4946 凸包 判重点 多校练习赛8 1002
- POJ 2187 Beauty Contest(凸包&&平面最远点对)
- POJ 2187 Beauty Contest (凸包)
- POJ 1113 Wall (凸包)
- POJ2187 n个点找距离最远的点对距离 graham 凸包