Sicily 4834. Party Location

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;

}                                 


 

發佈了135 篇原創文章 · 獲贊 6 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章