//大白p263
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <functional>
#include <set>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const double eps=1e-;//精度
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
inline int dcmp(const double& x){//判断double等于0或。。。
if(fabs(x)<eps)return ;else return x<?-:;
}
struct Point{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
typedef vector<Point> Polygon;
inline Vector operator+(const Vector& a,const Vector& b){return Vector(a.x+b.x,a.y+b.y);}//向量+向量=向量
inline Vector operator-(const Point& a,const Point& b){return Vector(a.x-b.x,a.y-b.y);}//点-点=向量
inline Vector operator*(const Vector& a,const double& p){return Vector(a.x*p,a.y*p);}//向量*实数=向量
inline Vector operator/(const Vector& a,const double& p){return Vector(a.x/p,a.y/p);}//向量/实数=向量
inline bool operator<( const Point& A,const Point& B ){return dcmp(A.x-B.x)<||(dcmp(A.x-B.x)==&&dcmp(A.y-B.y)<);}
inline bool operator==(const Point&a,const Point&b){return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;}
inline bool operator!=(const Point&a,const Point&b){return a==b?false:true;}
struct Segment{
Point a,b;
Segment(){}
Segment(Point _a,Point _b){a=_a,b=_b;}
inline bool friend operator<(const Segment& p,const Segment& q){return p.a<q.a||(p.a==q.a&&p.b<q.b);}
inline bool friend operator==(const Segment& p,const Segment& q){return (p.a==q.a&&p.b==q.b)||(p.a==q.b&&p.b==q.a);}
};
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point _c, double _r):c(_c),r(_r) {}
Point point(double a)const{return Point(c.x+cos(a)*r,c.y+sin(a)*r);}
bool friend operator<(const Circle& a,const Circle& b){return a.r<b.r;}
};
struct Line{
Point p;
Vector v;
double ang;
Line() {}
Line(const Point &_p, const Vector &_v):p(_p),v(_v){ang = atan2(v.y, v.x);}
inline bool operator<(const Line &L)const{return ang < L.ang;}
};
inline double Dot(const Vector& a,const Vector& b){return a.x*b.x+a.y*b.y;}//|a|*|b|*cosθ 点积
inline double Length(const Vector& a){return sqrt(Dot(a,a));}//|a| 向量长度
inline double Angle(const Vector& a,const Vector& b){return acos(Dot(a,b)/Length(a)/Length(b));}//向量夹角θ
inline double Cross(const Vector& a,const Vector& b){return a.x*b.y-a.y*b.x;}//叉积 向量围成的平行四边形的面积
inline double Area2(const Point& a,const Point& b,Point c){return Cross(b-a,c-a);}//同上 参数为三个点
inline double DegreeToRadius(const double& deg){return deg/*PI;}
inline double GetRerotateAngle(const Vector& a,const Vector& b){//向量a顺时针旋转theta度得到向量b的方向
double tempa=Angle(a,Vector(,));
if(a.y<) tempa=*PI-tempa;
double tempb=Angle(b,Vector(,));
if(b.y<) tempb=*PI-tempb;
if((tempa-tempb)>) return tempa-tempb;
else return tempa-tempb+*PI;
}
inline double torad(const double& deg){return deg/*PI;}//角度化为弧度
inline Vector Rotate(const Vector& a,const double& rad){//向量逆时针旋转rad弧度
return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
inline Vector Normal(const Vector& a){//计算单位法线
double L=Length(a);
return Vector(-a.y/L,a.x/L);
}
inline Point GetLineProjection(const Point& p,const Point& a,const Point& b){//点在直线上的投影
Vector v=b-a;
return a+v*(Dot(v,p-a)/Dot(v,v));
}
inline Point GetLineIntersection(Point p,Vector v,Point q,Vector w){//求直线交点 有唯一交点时可用
Vector u=p-q;
double t=Cross(w,u)/Cross(v,w);
return p+v*t;
}
int ConvexHull(Point* p,int n,Point* sol){//计算凸包
sort(p,p+n);
int m=;
for(int i=;i<n;i++){
while(m>&&dcmp(Cross(sol[m-]-sol[m-],p[i]-sol[m-]))<=) m--;
sol[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--){
while(m>k&&dcmp(Cross(sol[m-]-sol[m-],p[i]-sol[m-]))<=) m--;
sol[m++]=p[i];
}
if(n>) m--;
return m;
}
double Heron(double a,double b,double c){//海伦公式
double p=(a+b+c)/;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
bool SegmentProperIntersection(const Point& a1,const Point& a2,const Point& b1,const Point& b2){//线段规范相交判定
double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1);
double c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<&&dcmp(c3)*dcmp(c4)<;
}
double CutConvex(const int& n,Point* poly,const Point& a,const Point& b, vector<Point> result[]){//有向直线a b 切割凸多边形
vector<Point> points;
Point p;
Point p1=a,p2=b;
int cur,pre;
result[].clear();
result[].clear();
result[].clear();
if(n==) return ;
double tempcross;
tempcross=Cross(p2-p1,poly[]-p1);
if(dcmp(tempcross)==) pre=cur=;
else if(tempcross>) pre=cur=;
else pre=cur=;
for(int i=;i<n;i++){
tempcross=Cross(p2-p1,poly[(i+)%n]-p1);
if(dcmp(tempcross)==) cur=;
else if(tempcross>) cur=;
else cur=;
if(cur==pre){
result[cur].push_back(poly[(i+)%n]);
}
else{
p1=poly[i];
p2=poly[(i+)%n];
p=GetLineIntersection(p1,p2-p1,a,b-a);
points.push_back(p);
result[pre].push_back(p);
result[cur].push_back(p);
result[cur].push_back(poly[(i+)%n]);
pre=cur;
}
}
sort(points.begin(),points.end());
if(points.size()<){
return ;
}
else{
return Length(points.front()-points.back());
}
}
double DistanceToSegment(Point p,Segment s){//点到线段的距离
if(s.a==s.b) return Length(p-s.a);
Vector v1=s.b-s.a,v2=p-s.a,v3=p-s.b;
if(dcmp(Dot(v1,v2))<) return Length(v2);
else if(dcmp(Dot(v1,v3))>) return Length(v3);
else return fabs(Cross(v1,v2))/Length(v1);
}
inline bool isPointOnSegment(const Point& p,const Segment& s){
return dcmp(Cross(s.a-p,s.b-p))==&&dcmp(Dot(s.a-p,s.b-p))<;
}
int isPointInPolygon(Point p, Point* poly,int n){//点与多边形的位置关系
int wn=;
for(int i=;i<n;i++){
Point& p2=poly[(i+)%n];
if(isPointOnSegment(p,Segment(poly[i],p2))) return -;//点在边界上
int k=dcmp(Cross(p2-poly[i],p-poly[i]));
int d1=dcmp(poly[i].y-p.y);
int d2=dcmp(p2.y-p.y);
if(k>&&d1<=&&d2>)wn++;
if(k<&&d2<=&&d1>)wn--;
}
if(wn) return ;//点在内部
else return ;//点在外部
}
double PolygonArea(Point* p,int n){//多边形有向面积
double area=;
for(int i=;i<n-;i++)
area+=Cross(p[i]-p[],p[i+]-p[]);
return area/;
}
int GetLineCircleIntersection(Line L,Circle C,Point& p1,Point& p2){//圆与直线交点 返回交点个数
double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y-C.c.y;
double e = a*a + c*c, f = *(a*b+c*d), g = b*b + d*d -C.r*C.r;
double delta = f*f - *e*g;
if(dcmp(delta) < ) return ;//相离
if(dcmp(delta) == ) {//相切
p1=p1=L.p+L.v*(-f/(*e));
return ;
}//相交
p1=(L.p+L.v*(-f-sqrt(delta))/(*e));
p2=(L.p+L.v*(-f+sqrt(delta))/(*e));
return ;
}
double rotating_calipers(Point *ch,int n)//旋转卡壳
{
int q=;
double ans=;
ch[n]=ch[];
for(int p=;p<n;p++)
{
while(Cross(ch[q+]-ch[p+],ch[p]-ch[p+])>Cross(ch[q]-ch[p+],ch[p]-ch[p+]))
q=(q+)%n;
ans=max(ans,max(Length(ch[p]-ch[q]),Length(ch[p+]-ch[q+])));
}
return ans;
}
Polygon CutPolygon(Polygon poly,const Point& a,const Point& b){//用a->b切割多边形 返回左侧
Polygon newpoly;
int n=poly.size();
for(int i=;i<n;i++){
Point c=poly[i];
Point d=poly[(i+)%n];
if(dcmp(Cross(b-a,c-a))>=) newpoly.push_back(c);
if(dcmp(Cross(b-a,c-d))!=){
Point ip=GetLineIntersection(a,b-a,c,d-c);
if(isPointOnSegment(ip,Segment(c,d))) newpoly.push_back(ip);
}
}
return newpoly;
}
int GetCircleCircleIntersection(Circle c1,Circle c2,Point& p1,Point& p2){//求两圆相交
double d=Length(c1.c-c2.c);
if(dcmp(d)==){
if(dcmp(c1.r-c2.r)==) return -;//两圆重合
return ;
}
if(dcmp(c1.r+c2.r-d)<) return ;
if(dcmp(fabs(c1.r-c2.r)-d)>) return ;
double a=Angle(c2.c-c1.c,Vector(,));
double da=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(*c1.r*d));
p1=c1.point(a-da);p2=c1.point(a+da);
if(p1==p2) return ;
return ;
}
inline bool isPointOnleft(Point p,Line L){return dcmp(Cross(L.v,p-L.p))>;}//点在直线左边 线上不算
int HalfplaneIntersection(Line *L,int n,Point* poly){//半平面交
sort(L,L+n);
int first,last;
Point* p=new Point[n];
Line* q=new Line[n];
q[first=last=]=L[];
for(int i=;i<n;i++){
while(first<last&&!isPointOnleft(p[last-],L[i])) last--;
while(first<last&&!isPointOnleft(p[first],L[i])) first++;
q[++last]=L[i];
if(dcmp(Cross(q[last].v,q[last-].v))==){
last--;
if(isPointOnleft(L[i].p,q[last])) q[last]=L[i];
}
if(first<last) p[last-]=GetLineIntersection(q[last-].p,q[last-].v,q[last].p,q[last].v);
}
while(first<last&&!isPointOnleft(p[last-],q[first])) last--;
if(last-first<=) return ;
p[last]=GetLineIntersection(q[last].p,q[last].v,q[first].p,q[first].v);
int m=;
for(int i=first;i<=last;i++) poly[m++]=p[i];
return m;
}
//两点式化为一般式A = b.y-a.y, B = a.x-b.x, C = -a.y*(B)-a.x*(A);
//--------------------------------------
//--------------------------------------
//--------------------------------------
//--------------------------------------
//--------------------------------------
Point point[],ppoint[];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int tot = ;
double x,y,r;
for(int i = ;i<n;i++)
{
scanf("%lf%lf%lf",&x,&y,&r);
for(double j = ;j<*PI;j += 0.0032)
{
point[tot++] = Point(x+r*cos(j),y+r*sin(j));
}
}
for(int i = ;i<m;i++)
for(int j = ;j<;j++)
{
scanf("%lf%lf",&x,&y);
point[tot++] = Point(x,y);
}
tot=ConvexHull(point,tot,ppoint);
double ans = ;
Point pre = ppoint[];
for(int i = ;i<tot;i++)
{
ans += Length(ppoint[i]-pre);
pre = ppoint[i];
}
ans += Length(ppoint[]-pre);
printf("%.5f\n",ans);
}
return ;
}

hdu 4667 Building Fence < 计算几何模板>的更多相关文章

  1. HDU 4667 Building Fence 计算几何 凸包+圆

    1.三角形的所有端点 2.过所有三角形的端点对所有圆做切线,得到所有切点. 3.做任意两圆的外公切线,得到所有切点. 对上述所有点求凸包,标记每个点是三角形上的点还是某个圆上的点. 求完凸包后,因为所 ...

  2. HDU 4667 Building Fence(2013多校7 1002题 计算几何,凸包,圆和三角形)

    Building Fence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)To ...

  3. HDU 4667 Building Fence(求凸包的周长)

    A - Building Fence Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u ...

  4. HDU 4667 Building Fence

    题意: 给n个圆和m个三角形,且保证互不相交,用一个篱笆把他们围起来,求最短的周长是多少. 做法:--水过... 把一个圆均匀的切割成500个点,然后求凸包. 注意:求完凸包,在求周长的时候记得要把圆 ...

  5. HDU 5130 Signal Interference(计算几何 + 模板)

    HDU 5130 Signal Interference(计算几何 + 模板) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5130 Descripti ...

  6. 4667 Building Fence 解题报告

    题意:给n个圆和m个三角形,且保证互不相交,用一个篱笆把他们围起来,求最短的周长是多少. 解法1:在每个圆上均匀的取2000个点,求凸包周长就可以水过. 解法2:求出所有圆之间的外公切线的切点,以及过 ...

  7. [hdu4667]Building Fence 计算几何 瞎瘠薄搞

    大致题意: 给出n个圆和m个三角形,求最小的的,能将所有图形覆盖的图形的周长. 正解为求所有三角形顶点与圆的切点以及圆和圆的切点构造凸包,再求路径. 因为要求结果误差<=1e-3 所以 我们可以 ...

  8. lrj计算几何模板

    整理了一下大白书上的计算几何模板. #include <cstdio> #include <algorithm> #include <cmath> #include ...

  9. HDU 5033 Building(单调栈)

    HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...

随机推荐

  1. 复习FBV与CBV

    在学习DRF之前~我们要先复习一些知识点~~ FBV和CBV 学习Django的时候~我们已经学习过了CBV以及FBV~~我们来复习一下~~ 什么是FBV和CBV呢~~ FBV 基于函数的视图 CBV ...

  2. (7)centos7安装配置ftp服务器

    1.安装vsftpd yum install vsftpd -y 2.设置开机启动vsftpd ftp服务 systemctl enable vsftpd.service 3.启动vsftpd服务 s ...

  3. codevs——2102 石子归并 2(区间DP)

    时间限制: 10 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 在一个园形操场的四周摆放N堆石子,现要将石子有次序地 ...

  4. PHP的fsockopen方式访问接口慢的原因与优化方案

    在开发过程中常常遇到这样的需求,模拟浏览器访问某接口,并获取返回数据.我们比较常使用的方法是fsockopen与接口建立连接,然后发出指令,然后通过fgets接受返回值. 但是我们发现,通过PHP模拟 ...

  5. FAB使用在CoordinatorLayout的隐藏动画

    import android.content.Context; import android.os.Build; import android.support.design.widget.Coordi ...

  6. python+tesseract验证码识别的一点小心得

    由于公司需要,最近开始学习验证码的识别 我选用的是tesseract-ocr进行识别,据说以前是惠普公司开发的排名前三的,现在开源了.到目前为止已经出到3.0.2了 当然了,前期我们还是需要对验证码进 ...

  7. nginx configure 错误记录

    1.the HTTP rewrite module requires the PCRE library. ./configure: error: the HTTP rewrite module req ...

  8. hadoop datanode节点超时时间设置

    datanode进程死亡或者网络故障造成datanode无法与namenode通信,namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长. HDFS默认的超时时长为10分 ...

  9. C 作用域规则

    C 作用域规则 任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问.C 语言中有三个地方可以声明变量: 在函数或块内部的局部变量 在所有函数外部的全局变量 在形式参数的函 ...

  10. Python获取免费的可用代理

    Python获取免费的可用代理 在使用爬虫多次爬取同一站点时,常常会被站点的ip反爬虫机制给禁掉,这时就能够通过使用代理来解决.眼下网上有非常多提供最新免费代理列表的站点.这些列表里非常多的代理主机是 ...