可检验模板正确度
- An Easy Problem?!
- Ancient Berland Circus
- Open-air shopping malls
An Easy Problem?!
problem
就是大讨论
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
#define eps 1e-6struct vec {double x, y;vec(){}vec( double X, double Y ) { x = X, y = Y; }vec operator + ( vec t ) { return vec( x + t.x, y + t.y ); }vec operator - ( vec t ) { return vec( x - t.x, y - t.y ); }vec operator * ( double t ) { return vec( x * t, y * t ); }friend double dot( vec s, vec t ) { return s.x * t.x + s.y * t.y; }friend double cross( vec s, vec t ) { return s.x * t.y - s.y * t.x; }
};struct point {double x, y;point(){}point( double X, double Y ) { x = X, y = Y; }point operator + ( vec t ) { return point( x + t.x, y + t.y ); }vec operator - ( point t ) { return vec( x - t.x, y - t.y ); }
};struct line {point p; vec v;line(){}line( point P, vec V ) { p = P, v = V; }
};point intersect( line l, line r ) {return l.p + l.v * ( - ( cross( r.v, r.p - l.p ) / cross( l.v, r.v ) ) );
}bool seg_intersect( point p1, point p2, point p3, point p4 ) {double d1 = cross( p3 - p1, p4 - p1 ), d2 = cross( p3 - p2, p4 - p2 );double d3 = cross( p1 - p3, p2 - p3 ), d4 = cross( p1 - p4, p2 - p4 );if( d1 * d2 > 0 || d3 * d4 > 0 ) return 0;else return 1;
}int main() {int T; double x1, x2, y1, y2;scanf( "%d", &T );while( T -- ) {scanf( "%lf %lf %lf %lf", &x1, &y1, &x2, &y2 );point p1( x1, y1 ), p2( x2, y2 );scanf( "%lf %lf %lf %lf", &x1, &y1, &x2, &y2 );point p3( x1, y1 ), p4( x2, y2 );if( fabs( p2.y - p1.y ) < eps || fabs( p4.y - p3.y ) < eps ) {printf( "0.00\n" );continue;//有水平线case }if( p1.y > p2.y ) swap( p1, p2 );if( p3.y > p4.y ) swap( p3, p4 );line l( p1, p2 - p1 ), r( p3, p4 - p3 );if( fabs( l.v.x * r.v.y - l.v.y * r.v.x ) < eps ) {printf( "0.00\n" );continue;//两直线平行 (x1,y1)(x2,y2)->x1y2=x2y1; }if( ! seg_intersect( p1, p2, p3, p4 ) ) {printf( "0.00\n" );continue;//无交点 }point p = intersect( l, r );vec y( 0, 1 );if( cross( l.v, y ) * cross( r.v, y ) > 0 ) {//收集部分在竖直线一侧if( cross( l.v, r.v ) > 0 && p4.x - p2.x >= -eps ) {printf( "0.00\n" );continue;//收集部分l在r下面 且l被r遮挡完} if( cross( l.v, r.v ) < 0 && p2.x - p4.x >= -eps ) {printf( "0.00\n" );continue;//收集部分l在r上面 }}double ans_y = min( p2.y, p4.y ); //相似三角形解横坐标 double ans_x1 = p2.x + ( p1.x - p2.x ) * ( ans_y - p2.y ) / ( p1.y - p2.y );double ans_x2 = p4.x + ( p3.x - p4.x ) * ( ans_y - p4.y ) / ( p3.y - p4.y );double ans = ( ans_x1 - ans_x2 ) * ( ans_y - p.y ) / 2;//s=底x高/2 printf( "%.2f\n", fabs( ans ) + eps );}return 0;
}
Ancient Berland Circus
#include <cmath>
#include <cstdio>
#define eps 1e-2
double pi = acos( -1.0 );
struct point {double x, y;
}p[3];
double len[3], rad[3];double gcd( double x, double y ) {if( fabs( y ) < eps ) return x;else if( fabs( x ) < eps ) return y;else return gcd( y, fmod( x, y ) );
}double dis( int i, int j ) {return sqrt( ( p[i].x - p[j].x ) * ( p[i].x - p[j].x ) + ( p[i].y - p[j].y ) * ( p[i].y - p[j].y ) );
}int main() {for( int i = 0;i < 3;i ++ )scanf( "%lf %lf", &p[i].x, &p[i].y );double C = 0;for( int i = 0;i < 3;C += len[i], i ++ )len[i] = dis( i, ( i + 1 ) % 3 );C /= 2;double S = sqrt( C * ( C - len[0] ) * ( C - len[1] ) * ( C - len[2] ) );double R = len[0] * len[1] * len[2] / ( 4 * S );for( int i = 0;i < 2;i ++ )rad[i] = acos( 1 - len[i] * len[i] / ( 2 * R * R ) );rad[2] = 2 * pi - rad[0] - rad[1];double e = gcd( rad[0], gcd( rad[1], rad[2] ) );printf( "%.6f\n", pi * R * R * sin( e ) / e );return 0;
}
Open-air shopping malls
problem
枚举圆心,二分半径,然后求与每个圆相交面积,是否达到一半
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define eps 1e-10
#define maxn 25
int T, n;double pi = acos( -1.0 );int dcmp( double x ) {return fabs( x ) < eps ? 0 : ( x > 0 ? 1 : -1 );
}struct point {double x, y;point(){}point( double X, double Y ) { x = X, y = Y; }friend double dis( point p1, point p2 ) { return sqrt( ( p1.x - p2.x ) * ( p1.x - p2.x ) + ( p1.y - p2.y ) * ( p1.y - p2.y ) ); }
};struct circle {point o; double r;circle(){}circle( point O, double R ) { o = O, r = R; }
}C[maxn];double area_circle_intersect( circle c1, circle c2 ) {double d = dis( c1.o, c2.o );if( dcmp( d - c1.r - c2.r ) >= 0 ) return 0;if( dcmp( d - fabs( c1.r - c2.r ) ) <= 0 ) {double r = min( c1.r, c2.r );return pi * r * r;}double rad1 = acos( ( c1.r * c1.r + d * d - c2.r * c2.r ) / ( 2 * c1.r * d ) ); double rad2 = acos( ( c2.r * c2.r + d * d - c1.r * c1.r ) / ( 2 * c2.r * d ) );return rad1 * c1.r * c1.r + rad2 * c2.r * c2.r - c1.r * d * sin( rad1 );
}bool check( circle c ) {for( int i = 1;i <= n;i ++ )if( dcmp( area_circle_intersect( c, C[i] ) * 2 - pi * C[i].r * C[i].r ) < 0 )return 0;return 1;
}double solve( double l, double r, circle c ) {double ans;while( fabs( r - l ) > eps ) {double mid = ( l + r ) / 2;c.r = mid;if( check( c ) ) ans = mid, r = mid;else l = mid;}return ans;
}int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%lf %lf %lf", &C[i].o.x, &C[i].o.y, &C[i].r );double ans = 1e18;for( int i = 1;i <= n;i ++ ) {double l = 0, r = 0;for( int j = 1;j <= n;j ++ )r = max( r, C[j].r + dis( C[i].o, C[j].o ) );ans = min( ans, solve( l, r, C[i] ) );}printf( "%.4f\n", ans );}return 0;
}