【HAOI2008】bzoj1043 下落的圆盘

2023-11-07 19:48

本文主要是介绍【HAOI2008】bzoj1043 下落的圆盘,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

  有n个圆盘从天而降,后面落下的可以盖住前面的。求最后形成的封闭区域的周长。看下面这副图, 所有的红 色线条的总长度即为所求. Input

  第一行为1个整数n,N<=1000 接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标.

Output

  最后的周长,保留三位小数

可以算是【uva1308 Viva Confetti】的升级版。
这回不能 O(n3) 枚举判断每一段小圆弧是否被覆盖了,可以把一个圆和在他上面的圆交出的所有圆弧找出来,找到这些弧的并集的补集就是这个圆露出的部分。求并集的时候可以转化为序列上的问题,做法就很多了。

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const double eps=1e-8,pi=acos(-1);
int dcmp(double x)
{if (x>eps) return 1;if (fabs(x)<eps) return 0;return -1;
}
struct Vector
{double x,y;void rd(){scanf("%lf%lf",&x,&y);}Vector operator + (const Vector &v) const{return (Vector){x+v.x,y+v.y};}Vector operator - (const Vector &v) const{return (Vector){x-v.x,y-v.y};}Vector operator * (const int &k) const{return (Vector){x*k,y*k};}Vector operator / (const int &k) const{return (Vector){x/k,y/k};}
};
typedef Vector Point;
double dot(Vector v,Vector u)
{return v.x*u.x+v.y*u.y;
}
double cross(Vector v,Vector u)
{return v.x*u.y-v.y*u.x;
}
double length(Vector v)
{return sqrt(dot(v,v));
}
double dis(Point p,Point q)
{return length(p-q);
}
double convert(double a)
{while (dcmp(a)==-1) a+=2*pi;while (dcmp(a-2*pi)>=0) a-=2*pi;return a;
}
struct Circle
{Point o;double r;void rd(){scanf("%lf",&r);o.rd();}
}a[1010];
bool in(Circle c1,Circle c2)
{return dcmp(dis(c1.o,c2.o)-(c2.r-c1.r))<=0;
}
vector<pair<double,int> > ang;
vector<pair<double,int> >::iterator it;
void getintersection(Circle c1,Circle c2)
{double d=dis(c1.o,c2.o);if (dcmp(d-(c1.r+c2.r))>=0||dcmp(d-(c1.r-c2.r))<=0) return;double a1=atan2(c2.o.y-c1.o.y,c2.o.x-c1.o.x),a2=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));double s=convert(a1-a2),t=convert(a1+a2);if (dcmp(s-t)==1){ang.push_back(make_pair(0,1));ang.push_back(make_pair(t,-1));ang.push_back(make_pair(s,1));ang.push_back(make_pair(2*pi,-1));}else{ang.push_back(make_pair(s,1));ang.push_back(make_pair(t,-1));}
}
double count()
{double ret=0;int cnt=0;sort(ang.begin(),ang.end());if (ang.empty()) return 0;for (it=ang.begin();(it+1)!=ang.end();it++){cnt+=(*it).second;if (cnt) ret+=(*(it+1)).first-(*it).first;}return ret;
}
void check()
{for (it=ang.begin();it!=ang.end();it++)printf("%.3f %.3f\n",(*it).first,(*it).second);
}
int n;
int main()
{/*freopen("disc.in","r",stdin);freopen("disc.out","w",stdout);*/int ok;double ans=0;scanf("%d",&n);for (int i=1;i<=n;i++) a[i].rd();for (int i=1;i<=n;i++){ang.clear();ok=1;for (int j=i+1;j<=n&&ok;j++){if (in(a[i],a[j])) ok=0;else getintersection(a[i],a[j]);}if (ok) ans+=a[i].r*(2*pi-count());/*if (i==4) check();if (dcmp(ans)==-1){printf("%d\n",i);break;}*/}printf("%.3f\n",ans);
}

这篇关于【HAOI2008】bzoj1043 下落的圆盘的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/365889

相关文章

面试or笔试6——小球下落距离

小东和三个朋友一起在楼上抛小球,他们站在楼房的不同层,假设小东站的楼层距离地面N米,球从他手里自由落下,每次落地后反跳回上次下落高度的一半,并以此类推知道全部落到地面不跳,求4个小球一共经过了多少米?(数字都为整数) 给定四个整数A,B,C,D,请返回所求结果。 测试样例: 100,90,80,70 返回:1020 根据极限的思想可直接求得单个小球的下落距离之和为3*N c

NYISTOJ 63 小猴子下落 二叉树

小猴子下落 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 有一颗二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从左到右从上到下的编号为1,2,3,·····,2的D次方减1。在结点1处放一个小猴子,它会往下跑。每个内结点上都有一个开关,初始全部关闭,当每次有小猴子跑到一个开关上时,它的状态都会改变,当到达一个内结点时,如果

Algorithm学习笔记 --- 小球下落问题(二叉树解法)

有一颗二叉树,最大深度为D,且所有的叶子深度都相同。所有的结点从上到下从左到右编号为 1,2,3,4,....,2^D-1.在结点1处放一个小球,它会往下落。每个结点上都有一个开关,初始全部关闭,当每次有小球落到一个开关上时,它的状态都会改变。当小球到达一个内结点时,如果该结点上的开关关闭,则往左走,否则往右走,知道走到叶子结点。 一些小球从结点1处开始下落,最后一个小球会落到哪里呢?输入叶子深

【小球下落反弹】小球自由落下,每次落地后反跳回原高度的一半

一小球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高? 使用C语言实现,具体代码: #include<stdio.h>int main(){float sn=100.0,hn=sn/2;for(int n=2;n<=10;n++){sn=sn+2*hn;hn=hn/2;}printf("共经过%f米\n第10次反弹%f米高",

html圆盘钟表纯js有解释【搬代码】

结果如图所示: 使用的idear中的html编写 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-s

NYOJ 63 小猴子下落 二叉树之满二叉树

小猴子下落 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 3 描述 有一颗二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从左到右从上到下的编号为1,2,3,·····,2的D次方减1。在结点1处放一个小猴子,它会往下跑。每个内结点上都有一个开关,初始全部关闭,当每次有小猴子跑到一个开关上时,它的状态都会改变,当到达一个内结点时,如果开

63 小猴子下落

小猴子下落 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 3 描述 有一颗二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从左到右从上到下的编号为1,2,3,·····,2的D次方减1。在结点1处放一个小猴子,它会往下跑。每个内结点上都有一个开关,初始全部关闭,当每次有小猴子跑到一个开关上时,它的状态都会改变,当到达一个内结点

QT 圆盘百分比

1. /* 设置抗锯齿 */painter.setRenderHints(QPainter::Antialiasing, true);/* 最外层的圆 */QRect drawRect = event->rect();QRadialGradient gradient1(drawRect.center(), drawRect.width

NYOJ63小猴子的下落

小猴子下落 时间限制: 3000  ms   |  内存限制: 65535  KB 难度: 3 描述 有一颗二叉树,最大深度为D,且所有叶子的深度都相同。所有结点从左到右从上到下的编号为1,2,3,·····,2的D次方减1。在结点1处放一个小猴子,它会往下跑。每个内结点上都有一个开关,初始全部关闭,当每次有小猴子跑到一个开关上时,它的状态都会改变,当到达一个内结点时,如果

【双曲几何】圆盘上的三角形概念

目录 一、说明二、对偶三角形概念2.1 反演关系2.2 对偶关系2.3 找出三角形的对偶三角形 三、正交三角形概念3.1 通过对偶三角形,找到垂心3.2 正交三角形的概念3.3 中心射影点的概念 四、后记 一、说明 本文对双曲空间的三角形进行分析,本篇首先给出,参考圆内外的点映射,进而说明三角形形状的反演映射关系。进而给出正交三角图和射影中心的概念。我i们常常提到庞加莱盘的概念