2012年每周一赛第一场第三题。由于希望尽可能多的点可以被一个以2.5km为半径的圆所容纳,所以可以从半径为2.5km的且至少有两点在圆上的的圆去考虑。这样的话就依次选择两个点来画圆(有2个),再逐一判断有多少个点在当前圆内,输出最大值即可。另外由于是double类型,还有精度的问题要注意。
Run Time: 0.09sec
Run Memory: 304KB
Code Length: 2774Bytes
SubmitTime: 2012-03-01 21:11:23
// Problem#: 4834
// Submission#: 1228627
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cmath>
using namespace std;
struct Point {
double x, y;
void set( double a, double b ) { x = a; y = b; }
double distance( const Point& p ) { return sqrtl( powl( x - p.x, 2 ) + powl( y - p.y, 2 ) ); }
void adjust( double a, double b ) {
if ( x < a ) x = 2 * a - x;
if ( x > b ) x = 2 * b - x;
if ( y < a ) y = 2 * a - y;
if ( y > b ) y = 2 * b - y;
}
};
struct Equation {
double A, B, C;
void set( const Point& p1, const Point& p2 ) {
A = p1.y - p2.y;
B = -( p1.x - p2.x );
C = -( A * ( p1.x + p2.x ) / 2 + B * ( p1.y + p2.y ) / 2 );
}
void parallel( Equation& e1, Equation& e2, double d ) {
e1.A = e2.A = A;
e1.B = e2.B = B;
e1.C = C + d * sqrtl( powl( A, 2 ) + powl( B, 2 ) );
e2.C = C - d * sqrtl( powl( A, 2 ) + powl( B, 2 ) );
}
void vertical( Equation& e, const Point& p ) {
e.A = -B;
e.B = A;
e.C = -( e.A * p.x + e.B * p.y );
}
};
void node( Point& p1, Point& p2, const Equation& e, const Equation& e1, const Equation& e2 ) {
p1.x = -( e.A * e.C - e.B * e1.C ) / ( powl( e.A, 2 ) + powl( e.B, 2 ) );
p2.x = -( e.A * e.C - e.B * e2.C ) / ( powl( e.A, 2 ) + powl( e.B, 2 ) );
p1.y = -( e.B * e.C + e.A * e1.C ) / ( powl( e.A, 2 ) + powl( e.B, 2 ) );
p2.y = -( e.B * e.C + e.A * e2.C ) / ( powl( e.A, 2 ) + powl( e.B, 2 ) );
}
int main()
{
int n, t1, t2, max;
double dist;
Point point[ 200 ], center1, center2, mid;
Equation chord, parl1, parl2, radius;
int i, j, k;
n = 0;
while ( scanf( "%lf%lf", &point[ n ].x, &point[ n ].y ) != EOF )
n++;
max = ( n < 1 ? n: 1 );
for ( i = 0; i < n; i++ ) {
for ( j = i + 1; j < n; j++ ) {
if ( ( dist = point[ i ].distance( point[ j ] ) ) <= 5.0 ) {
mid.set( ( point[ i ].x + point[ j ].x ) / 2, ( point[ i ].y + point[ j ].y ) / 2 );
chord.set( point[ i ], point[ j ] );
chord.vertical( radius, mid );
chord.parallel( parl1, parl2, sqrtl( powl( 2.50, 2 ) - powl( dist / 2, 2 ) ) );
node( center1, center2, radius, parl1, parl2 );
t1 = t2 = 0;
center1.adjust( 0.0, 50.0 );
center2.adjust( 0.0, 50.0 );
for ( k = 0; k < n; k++ ) {
if ( center1.distance( point[ k ] ) <= 2.5001 )
t1++;
if ( center2.distance( point[ k ] ) <= 2.5001 )
t2++;
}
max = ( t1 > max ? t1: max );
max = ( t2 > max ? t2: max );
}
}
}
printf( "%d\n", max );
return 0;
}