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);
    	}
    }
    
  • 相关阅读:
    HDU 1069 Monkey and Banana
    HDU 1029 Ignatius and the Princess IV
    HDU 1024 Max Sum Plus Plus
    Gym100923H Por Costel and the Match
    Codeforces 682C Alyona and the Tree
    Codeforces 449B Jzzhu and Cities
    Codeforces (ccpc-wannafly camp day2) L. Por Costel and the Semipalindromes
    Codeforces 598D (ccpc-wannafly camp day1) Igor In the Museum
    Codeforces 1167c(ccpc wannafly camp day1) News Distribution 并查集模板
    快乐数问题
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039297.html
Copyright © 2011-2022 走看看