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 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章