lightoj 1358
题目大意:给定平面上的n个点和一个圆心的坐标,每一秒钟圆的半jing增加1,问几秒之后可以这个圆可以覆盖这个多边形的面积的P%.
思路:二分圆的半径,然后求圆覆盖。
const double PI = acos(-1.0); #define M 5010 class pnt_type { public: double x,y; }; class state_type { public: double angle; double CoverArea; }; pnt_type pnt[M]; pnt_type center; int n; double R; inline double Area2(pnt_type &a,pnt_type &b,pnt_type &c) { return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y); } inline double dot(pnt_type &a,pnt_type &b,pnt_type &c) { return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y); } inline double dist(pnt_type &a,pnt_type &b) { return sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y)); } double init() { int i; double temp,sum; for (i=2; i<n; i++) { temp = Area2(pnt[1],pnt[i],pnt[i + 1]); sum += temp; } if (sum < 0) reverse(pnt + 1,pnt + n + 1); pnt[n + 1] = pnt[1]; return sum/2; } inline bool inCircle(pnt_type &s) { return dist(center,s) <= R; } bool SameSide(pnt_type a,pnt_type b) { if (dist(a,center) > dist(b,center)) swap(a,b); return dot(a,b,center) < eps; } double ShadomOnCircle(pnt_type a,pnt_type b) { double flag = Area2(center,a,b),res = 0; if (fabs(flag) < eps) return 0; bool ina = inCircle(a),inb = inCircle(b); if (ina && inb) { res = fabs(Area2(center,a,b)) / 2; } else if (!ina && !inb) { if (SameSide(a,b)) { double theta = acos(dot(center,a,b) / dist(center,a) / dist(center,b)); res = R * R * theta / 2; } else { double height = fabs(Area2(center,a,b)) / dist(a,b); double theta = acos(dot(center,a,b) / dist(center,a) / dist(center,b)); if (height >= R) { res = R * R * theta / 2; } else { double _theta = 2 * acos(height / R); res = R * R * (theta - _theta) / 2 + R * R * sin(_theta) / 2; } } } else { if (!ina && inb) swap(a,b); double height = fabs(Area2(center,a,b)) / dist(a,b); double temp = dot(a,center,b); double theta = acos(dot(center,a,b) / dist(center,a) / dist(center,b)),theta1,theta2; if (fabs(temp) < eps) { double _theta = acos(height / R); res += R * height / 2 * sin(_theta); res += R * R / 2 * (theta - _theta); } else { theta1 = asin(height / R); theta2 = asin(height / dist(a,center)); if (temp > 0) { res += dist(center,a) * R / 2 * sin(PI - theta1 - theta2); res += R * R / 2 * (theta + theta1 + theta2 - PI); } else { res += dist(center,a) * R / 2 * sin(theta2 - theta1); res += R * R / 2 * (theta - theta2 + theta1); } } } if (flag < 0) return -res; else return res; } double Cover() { int i; double res = 0; for (i=1; i<=n; i++) res += ShadomOnCircle(pnt[i],pnt[i + 1]); return res; } int main() { double ans; int T; scanf("%d",&T); for(int tt=1; tt<=T; tt++) { double p; scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%lf%lf",&pnt[i].x,&pnt[i].y); scanf("%lf%lf%lf",¢er.x,¢er.y,&p); double totarea=init()*p/100; double l=0,r=3000; double mid; while(l<r-eps) { mid=(l+r)/2; R=mid; if(Cover()>=totarea)r=mid; else l=mid; } printf("Case %d: %.0lf\n",tt,l); } return 0; }
套模板的题。还没有过掉。
若是有人过掉了求告知。求科普。