POJ 3831 Open-air shopping malls

来源:互联网 发布:nginx ssl 多证书并存 编辑:程序博客网 时间:2024/05/21 04:43

题目大意:

题目链接

注释代码:

/*                                                 * Problem ID : POJ 3831 Open-air shopping malls * Author     : Lirx.t.Una                                                 * Language   : C++                                * Run Time   : 0 ms                                                 * Run Memory : 232 KB                                                */ #include <algorithm>#include <iostream>#include <cstdio>#include <cmath>using namespace std;const doubleINF= 1E10;const intMAXCIRN = 20;//圆的最大数量const doublePI  = 3.1415926535897932;const doubleESP = 1E-8;//精度控制structCir {doublex, y;//圆心坐标doubler;//半径Cir(void) {}Cir( double xx, double yy, double rr ) :x(xx), y(yy), r(rr) {}friend istream &operator>>(istream &is, Cir &cir) {is >> cir.x >> cir.y >> cir.r;return is;}doublePOW(double x) {return x * x;}doubleoperator^(Cir &oth) {//重载计算两个圆心之间的距离return sqrt( POW( x - oth.x ) + POW( y - oth.y ) );}doubleoperator/(Cir &oth) {//求本圆在oth圆中的楔形的面积doublea, b, c;doubleang;doubles1, s2;a = r;b = (*this) ^ oth;c = oth.r;ang = 2.0 * acos( ( POW(a) + POW(b) - POW(c) ) / ( 2.0 * a * b ) );//余弦公式求a、b之间的夹角angs1  = POW(a) * ang / 2.0;//求扇形面积s2  = POW(a) * sin(ang) / 2.0;//求三角形面积return s1 - s2;}doubleoperator*(Cir &oth) {//求重叠区域面积return (*this) / oth + oth / (*this);}booloperator>(Cir &oth) {//求两者重叠面积是否超过后者的一半doubledist;dist = (*this) ^ oth;//如果两圆无重叠if ( dist - ( r + oth.r ) > ESP ) return false;if ( fabs( r - oth.r )  - dist > ESP )//如果一个包在另一个里面if ( r - oth.r > ESP ) return true;//前者包含后者else return POW(r) * 2.0 - POW(oth.r) > ESP;//后者包含前者,但是需要检查前者面积是否超过后者一半return (*this) * oth * 2.0 - POW(oth.r) * PI > ESP;//否则就是正常的相交了}};intn;//圆的数量Circir[MAXCIRN];//Circleboolcheck(Cir &cc) {//检查圆cc是否和其它所有圆的重叠部分超过各圆面积的一半inti;for ( i = 0; i < n; i++ )if ( !( cc > cir[i] ) )return false;return true;}intmain() {intt;//测例数inti;//计数变量doublelft, rht, mid;//二分搜索doubleans;//最终的最小半径scanf("%d", &t);while ( t-- ) {scanf("%d", &n);for ( i = 0; i < n; i++ ) cin >> cir[i];ans = INF;for ( i = 0; i < n; i++ ) {//对每个位置逐个枚举lft = 0;rht = 50000;//二分最大断点while ( rht - lft > 1E-6 ) {//二分精度Circc( cir[i].x, cir[i].y, mid = ( lft + rht ) / 2.0);if ( check(cc) ) rht = mid;else lft = mid;}ans = min( ans, ( lft + rht ) / 2.0 );//更新每一个位置的结果对ans的改变}printf("%.4lf\n", ans);}return 0;}
无注释代码:

#include <algorithm>#include <iostream>#include <cstdio>#include <cmath>using namespace std;const doubleINF= 1E10;const intMAXCIRN = 20;const doublePI  = 3.1415926535897932;const doubleESP = 1E-8;structCir {doublex, y;doubler;Cir(void) {}Cir( double xx, double yy, double rr ) :x(xx), y(yy), r(rr) {}friend istream &operator>>(istream &is, Cir &cir) {is >> cir.x >> cir.y >> cir.r;return is;}doublePOW(double x) {return x * x;}doubleoperator^(Cir &oth) {return sqrt( POW( x - oth.x ) + POW( y - oth.y ) );}doubleoperator/(Cir &oth) {doublea, b, c;doubleang;doubles1, s2;a = r;b = (*this) ^ oth;c = oth.r;ang = 2.0 * acos( ( POW(a) + POW(b) - POW(c) ) / ( 2.0 * a * b ) );s1  = POW(a) * ang / 2.0;s2  = POW(a) * sin(ang) / 2.0;return s1 - s2;}doubleoperator*(Cir &oth) {return (*this) / oth + oth / (*this);}booloperator>(Cir &oth) {doubledist;dist = (*this) ^ oth;if ( dist - ( r + oth.r ) > ESP ) return false;if ( fabs( r - oth.r )  - dist > ESP )if ( r - oth.r > ESP ) return true;else return POW(r) * 2.0 - POW(oth.r) > ESP;return (*this) * oth * 2.0 - POW(oth.r) * PI > ESP;}};intn;Circir[MAXCIRN];boolcheck(Cir &cc) {inti;for ( i = 0; i < n; i++ )if ( !( cc > cir[i] ) )return false;return true;}intmain() {intt;inti;doublelft, rht, mid;doubleans;scanf("%d", &t);while ( t-- ) {scanf("%d", &n);for ( i = 0; i < n; i++ ) cin >> cir[i];ans = INF;for ( i = 0; i < n; i++ ) {lft = 0;rht = 50000;while ( rht - lft > 1E-6 ) {Circc( cir[i].x, cir[i].y, mid = ( lft + rht ) / 2.0);if ( check(cc) ) rht = mid;else lft = mid;}ans = min( ans, ( lft + rht ) / 2.0 );}printf("%.4lf\n", ans);}return 0;}

单词解释:


0 0