zoukankan      html  css  js  c++  java
  • BZOJ 1043: [HAOI2008]下落的圆盘

    暴力枚举每个圆后面的所有圆
    对这些圆每个与当前圆计算覆盖的弧度(有两个半径一个圆心距可以用余弦定理)
    把算出来的这些弧度存起来
    最后求个区间并,再计算剩余部分弧长
    (摘自CreationAugust 的博客)

    CODE

    #include <set>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 1005;
    const double eps = 1e-10;
    const double Pi = acos(-1.0);
    inline double sqr(double x) { return x*x; }
    struct Point {
    	double x, y;
    	inline Point(double _x=0, double _y=0): x(_x), y(_y){}
    	inline Point operator +(const Point &t)const { return Point(x + t.x, y + t.y); }
    	inline Point operator -(const Point &t)const {	return Point(x - t.x, y - t.y); }
    	inline double operator *(const Point &t)const { return x*t.y - y*t.x; } //cross
    	inline double operator ^(const Point &t)const { return x*t.x + y*t.y; } //dot
    	inline double dist(const Point &t)const { return sqrt(sqr(x-t.x) + sqr(y-t.y)); }
    	inline double len() { return dist(Point(0, 0)); }
    	inline double angle() { return atan2(y, x); }
    }O[MAXN];
    int n; double r[MAXN];
    set< pair<double, double> >S;
    
    inline double calc(double a, double b, double c) {
    	return acos((sqr(a)+sqr(b)-sqr(c))/(2*a*b));
    }
    
    int main ()
    {
    	int kase = 1;
    	//scanf("%d", &kase);
    	while(kase--) {
    		scanf("%d", &n);
    		for(int i = 1; i <= n; ++i)
    			scanf("%lf%lf%lf", &r[i], &O[i].x, &O[i].y);
    		double ans = 0;
    		for(int i = 1; i <= n; ++i) {
    			S.clear();
    			for(int j = i+1; j <= n; j++) {
    				double Len = O[i].dist(O[j]);
    				if(Len + r[i] > r[j] + eps && fabs(Len-r[i]) < r[j]){
    					double x = (O[j]-O[i]).angle(), y = calc(r[i], Len, r[j]);
    					double R = x + y, L = x - y;
    					if(L < -Pi) L += 2*Pi, R += 2*Pi;
    					if(R > Pi) S.insert(make_pair(L, Pi)), S.insert(make_pair(-Pi, R-2*Pi));
    					else S.insert(make_pair(L, R));
    				}
    				else if(Len + r[i] <= r[j] + eps)
    					S.insert(make_pair(-Pi, Pi));
    			}
    			set< pair<double, double> >::iterator it = S.begin();
    			double R = -Pi, sum = 0;
    			while(it != S.end()) {
    				if((*it).first > R) sum += (*it).first - R;
    				R = max(R, (*it).second); ++it;
    			}
    			sum += Pi - R;
    			ans += sum*r[i];
    		}
    		printf("%.3f
    ", ans);
    	}
    }
    
  • 相关阅读:
    msp430入门学习21--TA
    msp430入门学习20
    msp430入门学习17
    msp430入门学习16
    msp430入门学习15--时钟
    msp430入门学习14
    msp430入门学习13
    msp430入门学习12
    msp430入门学习11
    msp430入门学习10
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039297.html
Copyright © 2011-2022 走看看