標籤:style blog class code java color
題目來源:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=41
題意: 判斷一個可以移動的半圓最多可容納的點的個數 。
分析: 計算在圓內的點, 然後 枚舉 這些點, 將點 和 圓心 的連線 的直徑 的左右點 統計, 最大 值 即可。
代碼如下:
const double EPS = 1e-12;const int Max_N = 160;double add(double a, double b){ return (fabs(a + b) < EPS * ( fabs(a) + fabs(b) )) ? 0 : (a+ b) ;}struct Point{ double x, y; Point(){} Point(double x , double y):x(x), y(y){} double dist(Point p){ return sqrt( add( (x - p.x)*(x - p.x) , (y - p.y)*(y - p.y) ) ) ; } Point operator - (Point p){ return Point( add(x ,- p.x) , add(y, - p.y)) ; } double operator ^(Point p){ return add(x * p. y , - y * p.x) ; }}po[Max_N];Point ro ;double r ;int main(){ int n , i , j ,maxm ; while(scanf("%lf%lf%lf" , &ro.x , &ro.y , &r) && r > 0 ) { maxm = 0 ; scanf("%d" , &n) ; for(i = 0 ; i < n ; i++) scanf("%lf%lf" , &po[i].x ,&po[i].y ) ; int l = 0 ; for(i = 0 ; i< n ; i++) if( ro.dist(po[i]) - r <= EPS ) po[l++] = po[i] ; n = l ; int left , right; for(i = 0 ; i < n ; i++){ left = 0, right = 0; for(j = 0 ; j< n ; j++){ double d = (po[i] - ro)^(po[j] - ro) ; if( d > 0) left ++ ; else if( d < 0) right ++ ; else{ left ++ ; right ++ ; } } maxm = maxm < left? left :maxm ; maxm = maxm < right ? right : maxm ; } printf("%d\n" , maxm ) ; } return 0;}