2016湖南省省赛 J 三角形和矩形(计算几何)
https://ac.nowcoder.com/acm/contest/1112/J
把三角形的顶点里在矩形里面的点放进数组;
把矩形的顶点里在三角形里面的点放进数组;
把三角形三条边和矩形四条边的交点放进数组(规范相交);
对这个数组去重并求凸包然后求凸包面积就是答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int N=1e3+10; 5 double eps=1e-8; 6 double pi=acos(-1); 7 struct Point{ 8 double x,y; 9 Point(double x=0,double y=0):x(x),y(y){} 10 }; 11 typedef Point Vector; 12 Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);} 13 Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);} 14 Vector operator * (Vector A,double B){return Vector(A.x*B,A.y*B);} 15 Vector operator / (Vector A,double B){return Vector(A.x/B,A.y/B);} 16 int dcmp(double x){ 17 if(fabs(x)<eps)return 0; 18 else return x<0?-1:1; 19 } 20 bool operator < (const Point &a,const Point &b){ 21 return dcmp(a.x-b.x)<0||(dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)<0); 22 } 23 bool operator == (const Point &a,const Point &b){ 24 return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; 25 } 26 double Cross(Vector A,Vector B){ 27 return A.x*B.y-A.y*B.x; 28 } 29 double Dot(Vector A,Vector B){ 30 return A.x*B.x+A.y*B.y; 31 } 32 Point line_point(Point p,Vector v,Point q,Vector w){//直线交点 33 Vector u=p-q; 34 double t=Cross(w,u)/Cross(v,w); 35 return p+v*t; 36 } 37 bool onsegment(Point p,Point a1,Point a2){ 38 if(p==a1||p==a2)return true; 39 return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0; 40 } 41 bool segmentcross(Point a1,Point a2,Point b1,Point b2){ 42 double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1), 43 c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1); 44 return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0; 45 } 46 Point line_line(Point A,Point B,Point C,Vector D){//线段交点 47 if(segmentcross(A,B,C,D)){ 48 return line_point(A,B-A,C,D-C); 49 } 50 return Point(123.456,0); 51 } 52 int tubao(Point *p,int n,Point *ch){ 53 sort(p,p+n); 54 n=unique(p,p+n)-p; 55 int m=0; 56 for(int i=0;i<n;i++){ 57 while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--; 58 ch[m++]=p[i]; 59 } 60 int k=m; 61 for(int i=n-2;i>=0;i--){ 62 while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--; 63 ch[m++]=p[i]; 64 } 65 if(n>1)m--; 66 return m; 67 } 68 double tubaos(Point *p,int n){ 69 double area=0; 70 for(int i=1;i<n-1;i++){ 71 area+=Cross(p[i]-p[0],p[i+1]-p[0]); 72 } 73 return area/2; 74 } 75 int intubao(Point *ch,int n,Point p){ 76 Vector A,B; 77 int flag=0; 78 for(int i=0;i<n;i++){ 79 A=ch[(i+1)%n]-ch[i]; 80 B=p-ch[i]; 81 if(onsegment(p,ch[i],ch[(i+1)%n])){ 82 flag=-1; 83 break; 84 } 85 else if(Cross(A,B)>0){ 86 flag++; 87 } 88 } 89 if(flag==-1||flag==n)return 1; 90 return 0; 91 } 92 93 double x[N],y[N]; 94 Point p[N],q[N],ch[N],ans[N]; 95 int main(){ 96 while(~scanf("%lf%lf",&x[1],&y[1])){ 97 scanf("%lf%lf",&x[2],&y[2]); 98 scanf("%lf%lf",&x[3],&y[3]); 99 scanf("%lf%lf",&x[4],&y[4]); 100 int n=0; 101 p[n++]=Point(x[3],y[3]); 102 p[n++]=Point(x[4],y[3]); 103 p[n++]=Point(x[4],y[4]); 104 p[n++]=Point(x[3],y[4]); 105 106 int m=0; 107 q[m++]=Point(x[1],y[1]); 108 q[m++]=Point(x[1],y[2]); 109 q[m++]=Point(x[2],y[1]); 110 111 tubao(q,m,ch); 112 int cnt=0; 113 for(int i=0;i<n;i++){ 114 if(intubao(ch,m,p[i])){ 115 ans[cnt++]=p[i]; 116 } 117 } 118 for(int i=0;i<m;i++){ 119 if(intubao(p,n,q[i])){ 120 ans[cnt++]=q[i]; 121 } 122 } 123 p[n]=p[0]; 124 q[m]=q[0]; 125 for(int i=0;i<n;i++){ 126 for(int j=0;j<m;j++){ 127 Point A=line_line(p[i],p[i+1],q[j],q[j+1]); 128 if(dcmp(A.x-123.456)!=0)ans[cnt++]=A; 129 } 130 } 131 int n1=tubao(ans,cnt,ch); 132 if(n1<=2)printf("%.8lf\n",0.0); 133 else printf("%.8lf\n",tubaos(ch,n1)); 134 } 135 }