【BZOJ1043】[HAOI2008] 下落的圆盘
来源:互联网 发布:多益网络已经上市了吗 编辑:程序博客网 时间:2024/03/29 17:54
smg啊这种水题调了3h……前途一片灰暗……
对于每个圆,它能够把前面的圆覆盖,同时会被后面的圆覆盖,它所贡献的周长是它自身周长减去被覆盖的部分,而被覆盖的部分是可以算出来的,用当前圆暴力和后面的圆全部求个交。对于一个圆,它被另外一个圆给交了,其被覆盖的圆弧的圆心角是确定的。也就是说,这个圆被覆盖的总弧度可以用各个圆心角的并得到。每被覆盖一次,就可以得到一个被覆盖的弧度的区间。在平面直角坐标系上这个区间是
那么就把问题转化成了一些弧度区间的并。这个另开一篇文章讲好了。
求并的时间是
一开始把GetAng的返回值写成了bool
要注意圆覆盖的情况和同心圆的情况。这样用余弦定理算圆心角的时候会爆NaN。
woc用一个错误的标程对着调了几h
另外这个blog下的程序似乎是有错误的,可以被卡掉。
http://blog.csdn.net/jiangyuze831/article/details/40580789
my code:
#include <bits/stdc++.h>using namespace std;#define rep(i,a,b) for(int i=a,_=b;i<=_;i++)#define per(i,a,b) for(int i=a,_=b;i>=_;i--)#define pii pair<double , double>#define mp make_pair#define maxn 1007inline int rd() { char c = getchar(); while (!isdigit(c)) c = getchar() ; int x = c - '0'; while (isdigit(c = getchar())) x = x * 10 + c - '0'; return x;}const double pi = acos(-1.0);const double eps = 0;typedef vector<pii>::iterator iter_pii;template<class T> inline void upmax(T&a , T b) { if (a < b) a = b ; }template<class T> inline T sqr(T x) { return x * x ; }inline int fcmp(double a , double b) { if (fabs(a - b) <= eps) return 0; if (a < b - eps) return -1; return 1;}struct Point { double x , y; Point() { x = y = 0 ; } Point(double x , double y):x(x) , y(y) { } inline double GetAng() { return atan2(y , x); }};Point operator-(Point a , Point b) { return Point(a.x - b.x , a.y - b.y) ; }inline double GetPointDis(Point a , Point b) { return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)) ; }struct Circle { Point o; double r; Circle() {} Circle(double r , Point o):r(r) , o(o) { }}circle[maxn];int n;vector<pii> tmp;void input() { n = rd(); rep (i , 1 , n) { double r , x , y; scanf("%lf%lf%lf" , &r , &x , &y); circle[i] = Circle(r , Point(x , y)); }}void CircleIntersect(Circle&a , Circle&b) { double dis = GetPointDis(a.o , b.o); if (fcmp(dis , a.r + b.r) > 0 || fcmp(dis , a.r - b.r) < 0) return; if (fcmp(dis , b.r - a.r) <= 0 || (dis == 0 && a.r == b.r)) { tmp.push_back(mp(0 , pi + pi)); return; } //assert(a.r != 0); //assert(dis != 0); double theta = (b.o - a.o).GetAng() + pi , delta = acos((sqr(a.r) + sqr(dis) - sqr(b.r)) / (2.0 * a.r * dis)); if (theta < delta) { tmp.push_back(mp(0 , theta + delta)); tmp.push_back(mp(theta - delta + pi + pi , pi + pi)); } else if (theta + delta > pi + pi) { tmp.push_back(mp(theta - delta , pi + pi)); tmp.push_back(mp(0 , theta + delta - pi - pi)); } else { tmp.push_back(mp(theta - delta , theta + delta)); }}double calc(int i) { tmp.clear(); rep (j , i + 1 , n) CircleIntersect(circle[i] , circle[j]); sort(tmp.begin() , tmp.end()); double res = 0.0 , st = 0.0 , ed = 0.0; for (iter_pii it = tmp.begin() ; it != tmp.end() ; it ++) if (fcmp(it -> first , ed) > 0) res += ed - st , st = it -> first , ed = it -> second; else ed = max(ed , it -> second); res += ed - st; return (pi + pi - res) * circle[i].r;}void solve() { double ans = 0; per (i , n , 1) ans += calc(i); printf("%.3lf\n" , ans);}int main() { #ifndef ONLINE_JUDGE freopen("data.txt" , "r" , stdin); freopen("data.out" , "w" , stdout); #endif input(); solve(); return 0;}
0 0
- 【HAOI2008】【BZOJ1043】下落的圆盘
- 【BZOJ1043】[HAOI2008] 下落的圆盘
- bzoj1043: [HAOI2008]下落的圆盘
- bzoj1043 [HAOI2008]下落的圆盘
- BZOJ1043 [HAOI2008]下落的圆盘
- bzoj1043: [HAOI2008]下落的圆盘
- 【HAOI2008】bzoj1043 下落的圆盘
- bzoj1043: [HAOI2008]下落的圆盘
- 【BZOJ1043】【HAOI2008】下落的圆盘 计算几何
- bzoj1043 下落的圆盘 计算几何
- bzoj 1043: [HAOI2008]下落的圆盘
- BZOJ 1043 [HAOI2008]下落的圆盘
- BZOJ 1043 [HAOI2008]下落的圆盘
- bzoj 1043 [HAOI2008]下落的圆盘
- BZOJ 1043 [HAOI2008] 下落的圆盘 方法简析
- BZOJ 1043 HAOI2008 下落的圆盘 计算几何
- BZOJ 1043: [HAOI2008]下落的圆盘 计算几何,贪心,线段交
- BZOJ 1043 HAOI 2008 下落的圆盘 计算几何
- SQL 数据类型
- 2016年春运火车票预售期购票日历 (zz)
- 群策CRM解决方案,直击系统集成行业风口
- leetcode Pow(x, n) -- 简单重点
- 插播一条广告:LDA预测代码阅读
- 【BZOJ1043】[HAOI2008] 下落的圆盘
- UIview之间常用视图之间的切换方式
- mysql用java写的步骤
- SQL Server系列(8) -- 触发器
- leetcode 112 Path Sum(难易度:Easy)
- Android Jni调用浅述
- 如何判断一个NSString 是否包含了字符串
- 把数据保存到数据库附加表dede_addon时出错,原因是字段名不合法
- Codeforces Round #334 (Div. 2) A. Uncowed Forces