lightoj 1358
问圆和多边形相交,什么时候比例可以是一个定值。
二分加模板,可就是过不了。。。伤心。。。帖一发新模板,意思都一样,真是纠结了。
http://tokers.cn/2015/10/08/lightoj1358-fukushima-nuclear-blast%e4%ba%8c%e5%88%86%e5%9c%86%e5%92%8c%e5%a4%9a%e8%be%b9%e5%bd%a2%e6%b1%82%e4%ba%a4/
#include <iostream> #include <fstream> #include <cstring> #include <climits> #include <deque> #include <cmath> #include <queue> #include <stack> #include <ctime> #include <list> #include <map> #include <set> #include <utility> #include <sstream> #include <complex> #include <string> #include <vector> #include <cstdio> #include <bitset> #include <functional> #include <algorithm> using namespace std; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; const double eps = 1e-8; typedef long long LL; typedef unsigned long long ULL; typedef pair <int, int> PLL; const LL INF = (1LL << 60); const int N = 5010; int sgn(double x) { if (fabs(x) < eps) { return 0; } if (x < 0) { return -1; } return 1; } struct Point { double x, y; Point() {}; Point(double _x, double _y) { x = _x; y = _y; } void input() { scanf("%lf%lf", &x, &y); } double operator ^ (const Point &b) const { return x * b.y - y * b.x; } bool operator == (Point b) const { return sgn(x - b.x) == 0 && sgn(y - b.y) == 0; } bool operator < (Point b) const { return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : (x < b.x); } Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); } Point operator + (const Point &b) const { return Point(x + b.x, y + b.y); } Point operator / (const double &k) const { return Point(x / k, y / k); } double operator * (const Point &b) const { return x * b.x + y * b.y; } double distance(Point p) { return hypot(x - p.x, y - p.y); } double len() { return hypot(x, y); } double len2() { return x * x + y * y; } double rad(Point a, Point b) { Point p = *this; return fabs(atan2( fabs((a - p) ^ (b - p)), (a - p) * (b - p) )); } Point operator * (const double &k) const { return Point(x * k, y * k); } Point trunc(double r) { double l = len(); if (!sgn(l)) { return *this; } r /= l; return Point(x * r, y * r); } }; struct Line { Point s, e; Line(Point _s, Point _e) { s = _s; e = _e; } double length() { return s.distance(e); } double dispointtoline(Point p) { return fabs((p - s) ^ (e - s)) / length(); } Point lineprog(Point p) { return s + ( ((e - s) * ((e - s) * (p - s))) / ((e - s).len2()) ); } }; struct Circle { Point p; double r; Circle() {} Circle(Point _p, double _r) { p = _p; r = _r; } int pointcrossline(Line v, Point &p1, Point &p2) { if (!(*this).relationline(v)) { return 0; } Point a = v.lineprog(p); double d = v.dispointtoline(p); d = sqrt(r * r - d * d); if (sgn(d) == 0) { p1 = a; p2 = a; return 1; } p1 = a + (v.e - v.s).trunc(d); p2 = a - (v.e - v.s).trunc(d); return 2; } int relation(Point b) { double dst = b.distance(p); if (sgn(dst - r) < 0) { return 2; } else if (sgn(dst - r) == 0) { return 1; } return 0; } int relationline(Line v) { double dst = v.dispointtoline(p); if (sgn(dst - r) < 0) { return 2; } else if (sgn(dst - r) == 0) { return 1; } return 0; } double areatriangle(Point a, Point b) { if (sgn((p - a) ^ (p - b)) == 0) { return 0.0; } Point q[5]; int len = 0; q[len++] = a; Line l(a, b); Point p1, p2; if (pointcrossline(l, q[1], q[2]) == 2) { if (sgn( (a - q[1]) * (b - q[1]) ) < 0) { q[len++] = q[1]; } if (sgn( (a - q[2]) * (b - q[2]) ) < 0) { q[len++] = q[2]; } } q[len++] = b; if (len == 4 && sgn( (q[0] - q[1]) * (q[2] - q[1]) ) > 0) { swap(q[1], q[2]); } double res = 0; for (int i = 0; i < len - 1; ++i) { if (relation(q[i]) == 0 || relation(q[i + 1]) == 0) { double arg = p.rad(q[i], q[i + 1]); res += r * r * arg / 2.0; } else { res += fabs((q[i] - p) ^ (q[i + 1] - p)) / 2.0; } } return res; } }; struct Polygon { int n; Point p[N]; void input(int _n) { n = _n; for (int i = 0; i < n; ++i) { p[i].input(); } } double areacircle(Circle c) { double ans = 0; for (int i = 0; i < n; ++i) { int j = (i + 1) % n; if (sgn( (p[j] - c.p) ^ (p[i] - c.p) ) >= 0) { ans += c.areatriangle(p[i], p[j]); } else { ans -= c.areatriangle(p[i], p[j]); } } return fabs(ans); } double getarea() { double sum = 0; for (int i = 0; i < n; ++i) { sum += (p[i] ^ p[(i + 1) % n]); } return fabs(sum) / 2; } }pn; int main() { int t, icase = 1; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); pn.input(n); double x, y; int p; scanf("%lf%lf%d", &x, &y, &p); double sum = pn.getarea(); double l = 0, r = 5000, mid; double ans = 0; while (r - l > eps) { mid = (l + r) / 2; Circle c(Point(x, y), mid); double area = pn.areacircle(c); if (area - sum * p * 0.01 < -eps) { l = mid; } else { ans = mid; r = mid; } } printf("Case %d: %.0f\n", icase++, ans); } return 0; }
下面是我写的,也看不出来为什么错。
#include <cstdio> #include <cstring> #include <vector> #include <cmath> #include <stack> #include <cstdlib> #include <queue> #include <map> #include <iostream> #include <algorithm> #include <bits/stdc++.h> #include <queue> #include <ctime> using namespace std; const double Pi=acos(-1.0); const double eps=1e-10; struct point { double x,y; } a[5100]; double r; double x_mul(point a,point b,point c) { return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } double dist_1point(double x0,double y0) { return sqrt(x0*x0+y0*y0); } double dist_2point(double x1,double y1,double x2,double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } double dist_line(double x1,double y1,double x2,double y2) { double A,B,C,dist; A=y1-y2; B=x1-x2; C=x1*y2-x2*y1; dist=fabs(C)/sqrt(A*A+B*B); return dist; } double get_cos(double a,double b,double c) { double angel=(b*b+c*c-a*a)/(2*b*c); return angel; } point get_point(double x0,double y0) { double k; point temp; if(x0!=0) { k=y0/x0; temp.x=fabs(r)/sqrt(1+k*k); if(x0<0) temp.x=-temp.x; temp.y=k*temp.x; } else { temp.x=0; if(y0>0) temp.y=r; else temp.y=-r; } return temp; } int fi(double x1,double y1,double x2,double y2) { if (x1*y2-x2*y1>0) return 1; else return -1; } double get_area(double x1,double y1,double x2,double y2) { int sign=fi(x1,y1,x2,y2); double s; double l=dist_line(x1,y1,x2,y2); double a=dist_1point(x1,y1); double b=dist_1point(x2,y2); double c=dist_2point(x1,y1,x2,y2); if(a==0 || b==0) return 0; if(a<=r && b<=r) { s=fabs(x1*y2-x2*y1)/2.0; return s*sign; } else if(a>=r && b>=r && l>=r) { point t1=get_point(x1,y1); point t2=get_point(x2,y2); double d=dist_2point(t1.x,t1.y,t2.x,t2.y); double sita1=acos(get_cos(d,r,r)); double s=fabs(sita1*r*r/2.0); return s*sign; } else if(a>=r && b>=r && l<=r && (get_cos(a,b,c)<=0 || get_cos(b,a,c)<=0)) { point t1=get_point(x1,y1); point t2=get_point(x2,y2); double d=dist_2point(t1.x,t1.y,t2.x,t2.y); double sita=acos(get_cos(d,r,r)); s=fabs(sita*r*r/2.0); return s*sign; } else if(a>=r && b>=r && l<=r && (get_cos(a,b,c)>0 && get_cos(b,a,c)>0)) { double xx1,xx2,yy1,yy2; if(x1!=x2) { double k12=(y1-y2)/(x1-x2); double b12=y1-k12*x1; double a0=(1+k12*k12); double b0=(2*k12*b12); double c0=(b12*b12-r*r); xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0); yy1=k12*xx1+b12; xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0); yy2=k12*xx2+b12; } else { xx1=x1; xx2=x1; yy1=sqrt(r*r-x1*x1); yy2=-sqrt(r*r-x1*x1); } point t1=get_point(x1,y1); point t2=get_point(x2,y2); double d1=dist_2point(xx1,yy1,xx2,yy2); double d2=dist_2point(t1.x,t1.y,t2.x,t2.y); double sita1=acos(get_cos(d1,r,r)); double sita2=acos(get_cos(d2,r,r)); double s1=fabs(sita1*r*r/2.0); double s2=fabs(sita2*r*r/2.0); double s3=fabs(xx1*yy2-xx2*yy1)/2.0; s=s2+s3-s1; return s*sign; } else if(a>=r && b<=r) { double xxx,yyy; if(x1!=x2) { double k12=(y1-y2)/(x1-x2); double b12=y1-k12*x1; double a0=(1+k12*k12); double b0=(2*k12*b12); double c0=(b12*b12-r*r); double xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0); double yy1=k12*xx1+b12; double xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0); double yy2=k12*xx2+b12; if(x1<=xx1 && xx1<=x2 || x2<=xx1 && xx1<=x1) { xxx=xx1; yyy=yy1; } else { xxx=xx2; yyy=yy2; } } else { double xx1=x1; double yy1=-sqrt(r*r-x1*x1); double yy2=sqrt(r*r-x1*x1); if(y1<=yy1 && yy1<=y2 || y2<=yy1 && yy1<=y1) { yyy=yy1; xxx=xx1; } else { yyy=yy2; xxx=xx1; } } point t1=get_point(x1,y1); double ddd=dist_2point(t1.x,t1.y,xxx,yyy); double sita1=acos(get_cos(ddd,r,r)); double s1=fabs(sita1*r*r/2.0); double s3=fabs(xxx*y2-yyy*x2)/2.0; s=s1+s3; return s*sign; } else if(a<=r && b>=r) { double xxx,yyy; if(x1-x2!=0) { double k12=(y1-y2)/(x1-x2); double b12=y1-k12*x1; double a0=(1+k12*k12); double b0=(2*k12*b12); double c0=(b12*b12-r*r); double xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0); double yy1=k12*xx1+b12; double xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0); double yy2=k12*xx2+b12; if(x1<=xx1 && xx1<=x2 || x2<=xx1 && xx1<=x1) { xxx=xx1; yyy=yy1; } else { xxx=xx2; yyy=yy2; } } else { double yy1=-sqrt(r*r-x1*x1); double yy2=sqrt(r*r-x1*x1); double xx1=x1; if(y1<=yy1 && yy1<=y2 || y2<=yy1 && yy1<=y1) { yyy=yy1; xxx=xx1; } else { yyy=yy2; xxx=xx1; } } point t1=get_point(x2,y2); double ddd=dist_2point(t1.x,t1.y,xxx,yyy); double sita1=acos(get_cos(ddd,r,r)); double s1=fabs(sita1*r*r/2.0); double s3=fabs(xxx*y1-yyy*x1)/2.0; s=s1+s3; return s*sign; } else return 0; } int main() { // double area, x0, y0, v, angle, t, g; // // int i,n; // while(scanf("%lf%lf%lf%lf%lf%lf%lf", &x0, &y0, &v, &angle, &t, &g, &r)!=EOF) // { // if(fabs(x0)+fabs(y0)+fabs(v)+fabs(angle)+fabs(t)+fabs(g)+ // fabs(r)<0.0000001)break; // scanf("%d", &n); // for(i=0; i<n; i++) // scanf("%lf%lf", &a[i].x, &a[i].y); // area=0; // // // double xx,yy; // xx=x0+v*cos(angle/180.0*Pi)*t; // yy=y0+v*sin(angle/180.0*Pi)*t-0.5*g*t*t; // for(i=0; i<n; i++)//此模板精度高有很大一部分原因是把圆心定在原点 // a[i].x-=xx,a[i].y-=yy; // // //半径就是r // for(i=0; i<n; i++) // { // area+=get_area(a[i].x,a[i].y,a[(i+1)%n].x,a[(i+1)%n].y); // } // printf("%.2f\n",fabs(area)); // } int T,ncas=1; scanf ("%d",&T); while (T--) { int n; scanf ("%d",&n); for (int i=0; i<n; i++) { scanf ("%lf%lf",&a[i].x,&a[i].y); } double stdarea=0; for (int i=0; i<n; i++) { stdarea+=x_mul(a[i],a[(i+1)%n],a[(i+2)%n])/2.0; // printf ("%f\n",x_mul(a[i],a[(i+1)%n],a[(i+2)%n])/2.0); } stdarea=abs(stdarea)/2.0; // printf ("%f\n",stdarea); if (n==3) stdarea=abs(x_mul(a[0],a[(1)%n],a[(2)%n])/2.0); double area=0; double xx,yy,rate; scanf ("%lf%lf%lf",&xx,&yy,&rate); double L=0,R=0x7f7f7f7f,ans; while ((R-L)>eps) { r=(L+R)/2.0; area=0; for (int i=0; i<n; i++) { area+=get_area(a[i].x-xx,a[i].y-yy,a[(i+1)%n].x-xx,a[(i+1)%n].y-yy); } area=abs(area); double temp=area*100.0; if (temp-rate*stdarea>=-eps) { ans=r; R=r; } else L=r; } printf ("Case %d: %.0f\n",ncas++,ans); } return 0; }