An Easy Problem?!
就是大讨论
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
#define eps 1e-6
struct 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
枚举圆心,二分半径,然后求与每个圆相交面积,是否达到一半
#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;
}