#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> using namespace std; const double Pi=acos(-1.0); const double eps=1e-10; struct point { double x,y; }a[155]; double r; 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; 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)); } return 0; }
来自学长的模板,改成了自己模板的风格,其中分类的思想很明确。但是过不了light oj 1130。
题意是求多边形和圆面积交。
所以后来又在网上找了版子,这个版子两道题都能过。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> using namespace std; const double Pi=acos(-1.0); const double eps=1e-10; struct point { double x,y; }a[155]; double r; 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)); } return 0; }