【BZOJ1043】下落的圆盘 [计算几何]
下落的圆盘
Time Limit: 10 Sec Memory Limit: 162 MB
[Submit][Status][Discuss]
Description
有n个圆盘从天而降,后面落下的可以盖住前面的。求最后形成的封闭区域的周长。
看下面这副图, 所有的红色线条的总长度即为所求。

Input
第一行为1个整数n
接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标.
Output
最后的周长,保留三位小数
Sample Input
1 0 0
1 1 0
Sample Output
HINT
n <= 1000
Solution
显然是一道计算几何题。
考虑一个圆对于答案的贡献,显然是这个圆的周长 - 后面的圆把它覆盖掉的周长的并。那么我们就考虑怎么求这个并。
先考虑怎样记录下一个答案,显然直接扣掉单个圆对它的覆盖是不可行的,要减去重叠的情况。
既然边不可行,我们就用角度。显然,若我们求出 两圆交点的角度 即可解决这题。
我们考虑求圆A被圆B覆盖的角度:现在我们有两个圆的半径、圆心距。我们就可以得到 圆A与圆B的圆心连线 与 圆A半径 的夹角。
我们也可以知道 圆A与圆B的圆心连线 与 x轴的夹角。
这样的话,就可以把单个圆对于它的贡献记录到栈里面,最后扫一遍求一下剩余的角度,乘上R就是它对于答案的贡献了。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef unsigned long long s64; const int ONE = ;
const double pi = acos(-1.0); int n;
struct power
{
double x, y, r;
}a[ONE]; struct circle
{
double a, b;
}stk[ONE];
int top; double Ans; bool cmp(const circle &a, const circle &b)
{
if(a.a != b.a) return a.a < b.a;
return a.b < b.b;
} int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} double sqr(double x) {return x * x;}
double dist(power a, power b) {return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));} double Calc(power a, power b)
{
double A = a.r, B = b.r, C = dist(a, b);
double cosB = (sqr(A) + sqr(C) - sqr(B)) / ( * A * C);
double angle = atan2(a.x - b.x, a.y - b.y), add = acos(cosB);
stk[++top] = (circle){angle - add, angle + add};
} double init(power a, power b) {return a.r + dist(a, b) <= b.r;}
double sect(power a, power b) {return fabs(a.r - b.r) < dist(a, b) && dist(a, b) < a.r + b.r;} double Deal(int id)
{
top = ;
for(int i = id+; i <= n; i++)
if(init(a[id], a[i])) return ; for(int i = id+; i <= n; i++)
if(sect(a[id], a[i])) Calc(a[id], a[i]); for(int i = ; i <= top; i++)
{
while(stk[i].a < ) stk[i].a += * pi;
while(stk[i].b < ) stk[i].b += * pi;
if(stk[i].a > stk[i].b) stk[++top] = (circle){, stk[i].b}, stk[i].b = *pi;
} sort(stk + , stk + top + , cmp);
double last = 0.0, sum = 0.0;
for(int i = ; i <= top; i++)
if(stk[i].a > last) sum += stk[i].a - last, last = stk[i].b;
else last = max(last, stk[i].b); sum += * pi - last;
return a[id].r * sum;
} int main()
{
n = get();
for(int i = ; i <= n; i++)
scanf("%lf %lf %lf", &a[i].r, &a[i].x, &a[i].y);
for(int i = ; i <= n; i++)
Ans += Deal(i);
printf("%.3lf", Ans);
}
【BZOJ1043】下落的圆盘 [计算几何]的更多相关文章
- bzoj1043[HAOI2008]下落的圆盘 计算几何
1043: [HAOI2008]下落的圆盘 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1598 Solved: 676[Submit][Stat ...
- 【bzoj1043】[HAOI2008]下落的圆盘 计算几何
题目描述 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. 输入 第一行为1个整数n,N<=1000接下来n行每行3个实 ...
- bzoj1043 下落的圆盘
Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. Input 第一行为1个整数n,N<=100 ...
- BZOJ 1043 HAOI2008 下落的圆盘 计算几何
题目大意:n个圆盘依次下落.求终于能看到的轮廓线面积 円盘反对! 让我们一起团结起来! 赶走円盘! 咳咳.非常神的一道题 今天去看了题解和白书才搞出来-- 首先我们倒着做 对于每一个圆盘处理出在它之后 ...
- BZOJ 1043 [HAOI2008]下落的圆盘 ——计算几何
倒着考虑,加入一个圆,判断和前面有没有完全覆盖的情况. 如果没有,和圆盘一一取交集,然后计算它们的并集,然后计算即可. #include <map> #include <cmath& ...
- JZYZOJ1502 [haoi2008]下落的圆盘 计算几何 贪心
http://172.20.6.3/Problem_Show.asp?id=1502这种题用了快一天才写出来也是真的辣鸡.主要思路就是计算一下被挡住的弧度然后对弧度进行贪心.最开始比较困扰的是求弧度值 ...
- luogu P2510 [HAOI2008]下落的圆盘
LINK:下落的圆盘 计算几何.n个圆在平面上编号大的圆将编号小的圆覆盖求最后所有没有被覆盖的圆的边缘的总长度. 在做这道题之前有几个前置知识. 极坐标系:在平面内 由极点 极轴 和 极径组成的坐标系 ...
- 【bzoj1043】下落的圆盘
[bzoj1043]下落的圆盘 题意 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. \(1\leq n\leq 1000\ ...
- 【BZOJ1043】[HAOI2008]下落的圆盘 几何
[BZOJ1043][HAOI2008]下落的圆盘 Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. ...
随机推荐
- 由作业题引发对C++引用的一些思考
首先分析一段代码: #include <bits/c++config.h> #include <ostream> #include <iostream> #incl ...
- HTTP 请求头 & 响应头
HTTP请求头概述 HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST).如有必要,客户程序还可以选择发送其他的请求头.大多数请求头并不是必需的, 但Co ...
- iOS开发自定义试图切换
CATransition *transition = [CATransition animation]; transition.duration = 1.0f; transition.timingFu ...
- 解决chrome css本地映射不成功&&附带映射方法
解决办法:把本地文件夹名改成英文的(不要有中文) 顺便写一下怎么把在chrome调试的本地项目中的css映射到本地: 1.F12(option+command+i)启动chrome调试工具 2.打开s ...
- SQL 中 Date 与Datetime的区别
Date是SQL Server 2008新引进的数据类型.它表示一个日子,不包含时间部分,可以表示的日期范围从公元元年1月1日到9999年12月31日.只需要3个字节的存储空间. DateTime 日 ...
- [socket编程] 一个服务器与多个客户端之间通信
转自:http://blog.csdn.net/neicole/article/details/7539444 并加以改进 Server程序: // OneServerMain.cpp #includ ...
- bzoj4760[USACO2017 Jan]Hoof,Paper,Scissors
题意:玩n次剪刀石头布,对方每次出什么已经知道了.你出的招数必须是连续的几段(不能超过k+1段),问你最多赢几次.(n<=100000,k<=20) 正常做法:f[i][j][k]表示前i ...
- 【bzoj2223】[Coci 2009]PATULJCI 主席树
题目描述 样例输入 10 3 1 2 1 2 1 2 3 2 3 3 8 1 2 1 3 1 4 1 5 2 5 2 6 6 9 7 10 样例输出 no yes 1 no yes 1 no yes ...
- 【题解】HNOI2014世界树
脑子不清醒的时候千万别写题.写题写不下去了千万别死扛,重构才是你唯一的出路QAQ 昨天很想快点写道题,思路没有很清晰的时候就写了,结果……今天一怒之下决定重整思路重构代码,其实不过是半个小时的事情…… ...
- BZOJ2697 特技飞行 【贪心】
题目链接 BZOJ2697 题解 好水好水的贪心... 容易发现每种特技只表演两次,多表演没有意义,而且差距越长收益越大 然后就可以贪,最大的放两端,次大的往里,然后是第三大....... 证明很简单 ...