BZOJ2178 圆的面积并
<div class="post_brief"><p> 计算几何题。别人都用simpson搞。然后我决定不水一发,用hwd神犇在wc上讲的关键点法做。</p> 然后就搞到了12点半。发现坑数次。还专门用js写了个画圆的。当然我现在知道怎么画圆了。过两天去把oj7的统计图改一改。 思路是把所有圆的左右端点和所有圆的两两交的x提出来,unique一发(不然会tle显然的)。这样两个x之间的部分的圆弧是不会有交的。那么就可以视为一堆弓形和梯形了。然后扫描一下中位线的有效长度算梯形。每次新进入一个连通区域和出来的时候加相应弓形的面积。 需要注意按y排序的时候是按弓形与竖线的交点的y,而不是梯形的y,否则会有非常神奇的精度误差。另外算弓形面积必需要用反三角函数(至少我没研究出怎么不用)。如果用acos的话会暴精度暴得很惨。要用atan2来提高精度。 然后这样写连样例都会tle。仔细感受一下发现好像如果有一堆同心圆的话都会tle。然后考虑去掉包含的圆之后似乎就快了。然后就交了,然后居然跑过了。 然后来欣赏一下我的时间巨大,空间巨大,长度巨大。挤在一堆simpson里显得特别郁闷的代码。 #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const double eps = 1e-8; const double pi = acos(-1); inline int sgn(double x) { return (x > eps) - (x < -eps); } inline double sqr(double x) { return x * x; } typedef struct geo_obj { double x, y; geo_obj() {} geo_obj(double xo, double yo) { x = xo, y = yo; } inline void read() { scanf("%lf%lf", &x, &y); } inline geo_obj vertical() { return geo_obj(-y, x); } inline double len() { return sqrt(sqr(x) + sqr(y)); } } point, vect; inline geo_obj operator +(const geo_obj& a, const geo_obj& b) { return geo_obj(a....