题意:x=[-200,200],y=[-200,200]的平面,一天中太阳从不同角度射到长椅(原点(0,0))上,有一些树(用圆表示),问哪个时刻(分钟为单位)太阳光线与这些圆所交的弦长总和最长。太阳距离原点总是500m。(这些圆不会互相相交,每个圆都不包括原点或者不经过原点)
解法:直接暴力24*60分钟,找出此时的角度,然后求出直线方程,再枚举每个圆,求出弦长。注意这里每个圆都不包括原点,所以直线与圆的交点一定在同一侧,所以。。我当时想多了,没看清题目。把他当成可以包含原点了,代码超长,幸好过了。
代码:
没想多应该这样就可以了:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #define INint 2147483647 #define pi acos(-1.0) #define eps 1e-4 using namespace std; #define N 100102 #define M 22 typedef struct point { double x,y; point(double x=0,double y=0):x(x),y(y){} }Vector; double DegtoRad(double deg) { return deg/180.0*pi; } int dcmp(double x) { if(fabs(x)<eps) return 0; return x<0?-1:1; } Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);} Vector operator - (point A,point B){return Vector(A.x-B.x,A.y-B.y); } Vector operator * (Vector A,double p){return Vector(A.x*p,A.y*p);} Vector operator / (Vector A,double p){return Vector(A.x/p,A.y/p);} bool operator == (const point& a,const point& b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;} bool operator < (const point& a,const point& b){return a.x<b.x ||(a.x==b.x&&a.y<b.y);} double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;} //叉积 ,大于零说明B在A的左边。小于零说明B在A的右边 double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;} //点积 double length(Vector A){return sqrt(Dot(A,A));} //向量长度 double DistanceToSegment(point P,point A,point B) { if(A==B) return length(P-A); Vector v1=B-A,v2=P-A,v3=P-B; if(dcmp(Dot(v1,v2))<0) return length(v2); else if(dcmp(Dot(v1,v3))>0) return length(v3); else return fabs(Cross(v1,v2))/length(v1); } point p[205]; double ra[205]; int main() { int n,i,j; while(scanf("%d",&n)!=EOF && n) { for(i=0;i<n;i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&ra[i]); double maxi = 0.0; int S = 24*60; for(i=0;i<S;i++) { point A,B,C; A = point(0.0,0.0); double rad = DegtoRad(i/4.0); B = point(500*sin(rad),500*cos(rad)); double sum = 0.0; for(j=0;j<n;j++) { C = p[j]; double dis = DistanceToSegment(C,A,B); if(dis >= ra[j]) continue; sum += 2.0*sqrt(ra[j]*ra[j]-dis*dis); } maxi = max(maxi,sum); } printf("%.3lf\n",maxi); } return 0; }