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

    /*
    对于每个圆, 考虑之后所有的圆覆盖了他的哪些部分即可
    所以我们要实现两圆求交点, 区间求并
    
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<cmath>
    #define ll long long
    #define M 2010
    #define mmp make_pair
    using namespace std;
    const double pi = acos(-1.0);
    int read() {
    	int nm = 0, f = 1;
    	char c = getchar();
    	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    	return nm * f;
    }
    struct C {
    	double x, y, r;
    } cir[M];
    struct Note {
    	double p;
    	int v;
    	bool operator < (const Note &b) const {
    		return this->p < b.p;
    	}
    } note[M];
    int n;
    double ans, diss;
    double dis(C a, C b) {
    	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    int main() {
    	n = read();
    	for(int i = 1; i <= n; i++) scanf("%lf%lf%lf", &cir[i].r, &cir[i].x, &cir[i].y);
    	for(int i = 1; i <= n; i++) {
    		int f = false, tp = 0, sum = 0;
    		for(int j = i + 1; j <= n; j++) {
    			diss = dis(cir[i], cir[j]);
    			if(diss + cir[i].r <= cir[j].r) {
    				f = true;
    				break;
    			}
    			if(diss > cir[i].r + cir[j].r) continue;
    			if(diss + cir[j].r <= cir[i].r) continue;
    		//	if(diss <= fabs(cir[i].r - cir[j].r)) continue;
    			double a = acos((cir[i].r * cir[i].r + diss * diss - cir[j].r * cir[j].r) / (2.0 * cir[i].r * diss));
    			double b = atan2(cir[j].y - cir[i].y, cir[j].x - cir[i].x);
    			note[++tp] = (Note) {
    				b - a, 1
    			};
    			note[++tp] = (Note) {
    				b + a, -1
    			};
    			if(note[tp - 1].p < 0) note[tp - 1].p += 2 * pi;
    			if(note[tp - 1].p > 2 * pi) note[tp - 1].p -= 2 * pi;
    			if(note[tp].p < 0) note[tp].p += 2 * pi;
    			if(note[tp].p > 2 * pi) note[tp].p -= 2 * pi;
    			if(note[tp - 1].p > note[tp].p) sum++;
    		}
    		if(f) continue;
    		ans += cir[i].r * 2 * pi;
    		if(!tp) continue;
    		sort(note + 1, note + tp + 1);
    		for(int j = 1; j <= tp; j++) {
    			if(sum) ans -= cir[i].r * (note[j].p - note[j - 1].p);
    			sum += note[j].v;
    		}
    		if(sum) ans -= cir[i].r * (2 * pi - note[tp].p);
    	}
    	printf("%.3lf
    ", ans);
    	return 0;
    }
    /*
    5
    0.743 0.247 -0.594
    0.051 0.837 0.239
    0.257 0.617 -0.676
    0.780 -0.119 -0.547
    0.091 0.318 -0.661
    
    */
    
    
    
  • 相关阅读:
    MapReduce原理
    《软件需求十步走》阅读笔记3
    《软件需求十步走》阅读笔记2
    《软件需求十步走》阅读笔记1
    2017秋季阅读计划
    怎么做需求分析
    兴趣小组第一次
    第十天
    第九天
    对UC的分析(个人观点,多多包涵)
  • 原文地址:https://www.cnblogs.com/luoyibujue/p/10530511.html
Copyright © 2011-2022 走看看