当前位置: 首页 > 编程日记 > 正文

【kuangbin专题】计算几何_半平面交

1.poj3335 Rotating Scoreboard

传送:http://poj.org/problem?id=3335

题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的,问你是否在球场上有个地方可以放一个记分牌,然后所有的观众都可以看得到的。

分析:多边形是否存在内核。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int maxn=110;
 7 const double eps=1e-8;
 8 int sgn(double x){
 9     if (fabs(x)<eps) return 0;
10     if (x<0) return -1;
11     return 1;
12 }
13 struct point{
14     double x,y;
15     point(){}
16     point(double _x,double _y):x(_x),y(_y){}
17     point operator -(const point &b)const{
18         return point(x-b.x,y-b.y);
19     }
20     double operator ^(const point &b)const{
21         return x*b.y-y*b.x;
22     }
23 }p[maxn];
24 struct line{
25     point s,e;
26     line(){}
27     line(point _s,point _e):s(_s),e(_e){}
28     point crosspoint(line v){
29         int a1=(v.e-v.s)^(s-v.s),a2=(v.e-v.s)^(e-v.s);
30         return point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
31     }
32     //两向量平行(对应直线平行或重合)
33     bool parallel(line v){
34         return sgn((e-s)^(v.e-v.s))==0;
35     } 
36 };
37 struct halfplane:public line{
38     double angle;
39     halfplane(){}
40     halfplane(line v){s=v.s;e=v.e;}
41     void calcangle(){
42         angle=atan2(e.y-s.y,e.x-s.x);
43     }
44     bool operator <(const halfplane &b)const{
45         return angle<b.angle;
46     }
47 };
48 struct halfplanes{
49     int n;
50     halfplane hp[maxn];
51     point p[maxn];
52     int que[maxn]; int st,ed;  //双端队列
53     void push(halfplane tmp){hp[n++]=tmp;}
54     //去重
55     void unique(){
56         int m=1;
57         for (int i=1;i<n;i++){
58             if (sgn(hp[i].angle-hp[i-1].angle)!=0) hp[m++]=hp[i];
59             else if (sgn((hp[m-1].e-hp[m-1].s)^(hp[i].s-hp[m-1].s))>0) hp[m-1]=hp[i];
60         }
61         n=m;
62     } 
63     bool halfplaneinsert(){
64         for (int i=0;i<n;i++) hp[i].calcangle();
65         sort(hp,hp+n);
66         unique();
67         que[st=0]=0; que[ed=1]=1;
68         p[1]=hp[0].crosspoint(hp[1]);
69         for (int i=2;i<n;i++){
70             while (st<ed && sgn((hp[i].e-hp[i].s)^(p[ed]-hp[i].s))<0) ed--;
71             while (st<ed && sgn((hp[i].e-hp[i].s)^(p[st+1]-hp[i].s))<0) st++;
72             que[++ed]=i;
73             if (hp[i].parallel(hp[que[ed-1]])) return false;
74             p[ed]=hp[i].crosspoint(hp[que[ed-1]]);
75         }
76         while (st<ed && sgn((hp[que[st]].e-hp[que[st]].s)^(p[ed]-hp[que[st]].s))<0) ed--;
77         while (st<ed && sgn((hp[que[ed]].e-hp[que[ed]].s)^(p[st+1]-hp[que[ed]].s))<0) st++;
78         if (st+1>=ed) return false; else return true;
79     }
80 };
81 halfplanes ha;
82 int main(){
83     int t,n; cin >>t;
84     while (t--){
85         cin >> n;
86         ha.n=0;
87         for (int i=0;i<n;i++) cin >> p[i].x >> p[i].y;
88         for (int i=0;i<n;i++){
89             ha.push(halfplane(line(p[i],p[(i-1+n)%n])));
90         }
91         if (ha.halfplaneinsert()) cout << "YES\n"; else cout << "NO\n";
92     }
93     return 0;
94 }
poj3335

2.poj1279 Art Gallery

传送:http://poj.org/problem?id=1279

题意:给一个多边形(顺时针给出点),求内核面积。

分析:rt。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 using namespace std;
  6 const int maxn=1505;
  7 const double eps=1e-8;
  8 int sgn(double x){
  9     if (fabs(x)<eps) return 0;
 10     if (x<0) return -1;
 11     return 1;
 12 }
 13 struct point{
 14     double x,y;
 15     point(){}
 16     point(double _x,double _y):x(_x),y(_y){}
 17     point operator -(const point &b)const{
 18         return point(x-b.x,y-b.y);
 19     }
 20     double operator ^(const point &b)const{
 21         return x*b.y-y*b.x;
 22     }
 23 }p[maxn];
 24 struct line{
 25     point s,e;
 26     line(){}
 27     line(point _s,point _e):s(_s),e(_e){}
 28     point crosspoint(line v){
 29         int a1=(v.e-v.s)^(s-v.s),a2=(v.e-v.s)^(e-v.s);
 30         return point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
 31     }
 32     //两向量平行(对应直线平行或重合)
 33     bool parallel(line v){
 34         return sgn((e-s)^(v.e-v.s))==0;
 35     } 
 36 };
 37 struct polygon{
 38     int n;
 39     point p[maxn];
 40     double getarea(){
 41         double sum=0;
 42         for (int i=0;i<n;i++) sum+=(p[i]^(p[(i+1)%n]));
 43         return fabs(sum)/2; 
 44     }
 45 };
 46 struct halfplane:public line{
 47     double angle;
 48     halfplane(){}
 49     halfplane(line v){s=v.s;e=v.e;}
 50     void calcangle(){
 51         angle=atan2(e.y-s.y,e.x-s.x);
 52     }
 53     bool operator <(const halfplane &b)const{
 54         return angle<b.angle;
 55     }
 56 };
 57 polygon C;
 58 struct halfplanes{
 59     int n;
 60     halfplane hp[maxn];
 61     point p[maxn];
 62     int que[maxn]; int st,ed;  //双端队列
 63     void push(halfplane tmp){hp[n++]=tmp;}
 64     //去重
 65     void unique(){
 66         int m=1;
 67         for (int i=1;i<n;i++){
 68             if (sgn(hp[i].angle-hp[i-1].angle)!=0) hp[m++]=hp[i];
 69             else if (sgn((hp[m-1].e-hp[m-1].s)^(hp[i].s-hp[m-1].s))>0) hp[m-1]=hp[i];
 70         }
 71         n=m;
 72     } 
 73     bool halfplaneinsert(){
 74         for (int i=0;i<n;i++) hp[i].calcangle();
 75         sort(hp,hp+n);
 76         unique();
 77         que[st=0]=0; que[ed=1]=1;
 78         p[1]=hp[0].crosspoint(hp[1]);
 79         for (int i=2;i<n;i++){
 80             while (st<ed && sgn((hp[i].e-hp[i].s)^(p[ed]-hp[i].s))<0) ed--;
 81             while (st<ed && sgn((hp[i].e-hp[i].s)^(p[st+1]-hp[i].s))<0) st++;
 82             que[++ed]=i;
 83             if (hp[i].parallel(hp[que[ed-1]])) return false;
 84             p[ed]=hp[i].crosspoint(hp[que[ed-1]]);
 85         }
 86         while (st<ed && sgn((hp[que[st]].e-hp[que[st]].s)^(p[ed]-hp[que[st]].s))<0) ed--;
 87         while (st<ed && sgn((hp[que[ed]].e-hp[que[ed]].s)^(p[st+1]-hp[que[ed]].s))<0) st++;
 88         if (st+1>=ed) return false; else return true;
 89     }
 90     //得到最后半平面交的凸多边形
 91     //得到先调用halfplaneinsert(),且返回true
 92     void getconvex(polygon &con){
 93         p[st]=hp[que[st]].crosspoint(hp[que[ed]]);
 94         con.n=ed-st+1;
 95         for (int j=st,i=0;j<=ed;j++,i++) con.p[i]=p[j];
 96     } 
 97 };
 98 halfplanes ha;
 99 int main(){
100     int t,n; cin >> t;
101     while (t--){
102         cin >> n;
103         for (int i=0;i<n;i++) cin >> p[i].x >> p[i].y;
104         ha.n=0;
105         for (int i=0;i<n;i++) ha.push(line(p[i],p[(i-1+n)%n]));
106         ha.halfplaneinsert();
107         C.n=0;
108         ha.getconvex(C);
109         printf("%.2f\n",C.getarea());
110     }
111     return 0;
112 } 
poj1279

3.poj3525 Most Distant Point from the Sea

传送:http://poj.org/problem?id=3525

题意:给出一个海岛,求出岛上离海最远的点。输出距离。

分析:半平面交+二分。就是求多边形的最大半径圆   //板子

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 using namespace std;
  6 const double eps=1e-8;
  7 const int maxn=110;
  8 inline double sqr(double x){return x*x;}
  9 int N;
 10 int sgn(double x){
 11     if (fabs(x)<eps) return 0;
 12     if (x<0) return -1;
 13     return 1;
 14 }
 15 struct point{
 16     double x,y;
 17     point(){}
 18     point(double _x,double _y):x(_x),y(_y){}
 19     point operator -(const point &b)const{
 20         return point(x-b.x,y-b.y);
 21     }
 22     double operator ^(const point &b)const{
 23         return x*b.y-y*b.x;
 24     }
 25 };
 26 struct line{
 27     point s,e;
 28     double k; //斜率 
 29     line(){}
 30     line(point _s,point _e):s(_s),e(_e){k=atan2(e.y-s.y,e.x-s.x);}
 31     point operator &(const line &b)const{ //求两直线交点
 32         point res=s;
 33         double t=((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
 34         res.x+=(e.x-s.x)*t; res.y+=(e.y-s.y)*t;
 35         return res;
 36     }
 37 };
 38 point p[maxn]; //记录最初给的点集
 39 line L[maxn]; //由最初的点集生成直线的集合
 40 point pp[maxn]; //记录半平面交的结果的点集
 41 //半平面交,直线的左边代表有效区域
 42 bool HPIcmp(line a,line b){  //直线排序函数
 43     if(sgn(a.k-b.k)!=0) return a.k<b.k; //斜率排序
 44     //斜率相同我也不知道怎么办
 45     return ((a.s-b.s)^(b.e-b.s))<0;
 46 }
 47 void HPI(line L[],int n,point res[],int &resn){ 
 48 //line是半平面交的直线的集合 n是直线的条数 res是结果
 49 //的点集 resn是点集里面点的个数
 50     int tot=n;
 51     sort(L,L+n,HPIcmp);
 52     tot=1;
 53     //去掉斜率重复的
 54     for(int i=1;i<n;i++) if(sgn(L[i].k-L[i-1].k)!=0) L[tot++]=L[i];
 55     int head,tail; line Q[maxn];  //双端队列 
 56     Q[head=0]=L[0]; Q[tail=1]=L[1];
 57     resn=0;
 58     for(int i=2;i<tot;i++){
 59         if(sgn((Q[tail].e-Q[tail].s)^(Q[tail-1].e-Q[tail-1].s))==0||
 60         sgn((Q[head].e-Q[head].s)^(Q[head+1].e-Q[head+1].s))==0) return;
 61         while(head<tail && (((Q[tail]&Q[tail-1])-L[i].s)^(L[i].e-L[i].s))>eps) tail--;
 62         while(head<tail && (((Q[head]&Q[head+1])-L[i].s)^(L[i].e-L[i].s))>eps) head++;
 63         Q[++tail]=L[i];
 64     }
 65     while(head<tail && (((Q[tail]&Q[tail-1])-Q[head].s)^(Q[head].e-Q[head].s))>eps) tail--;
 66     while(head<tail && (((Q[head]&Q[head-1])-Q[tail].s)^(Q[tail].e-Q[tail].e))>eps) head++;
 67     if(tail<=head+1) return;
 68     for(int i=head;i<tail; i++) res[resn++]=Q[i]&Q[i+1];
 69     if(head<tail-1) res[resn++]=Q[head]&Q[tail];
 70 }
 71 double dist(point a,point b){
 72     return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
 73 }
 74 void change(point p1,point p2,point &a,point &b,double p){
 75     double len=dist(p1,p2);
 76     double dx=(p1.y-p2.y)*p/len,dy=(p2.x-p1.x)*p/len;
 77     a.x=p1.x+dx;a.y=p1.y+dy;
 78     b.x=p2.x+dx;b.y=p2.y+dy;
 79 }
 80 bool check(double mid){
 81     for (int i=0;i<N;i++){
 82         point a,b;
 83         change(p[i],p[(i+1)%N],a,b,mid);
 84         L[i]=line(a,b);
 85     }
 86     int resn;
 87     HPI(L,N,pp,resn); //resn等于0说明移多了
 88     if (resn==0) return false; else return true;    
 89 }
 90 int main(){
 91     while (cin >> N && N){
 92         for (int i=0;i<N;i++)
 93             cin >> p[i].x >> p[i].y;
 94         double l=0,r=100000,mid;
 95         double ans;
 96         while (r-l>=eps){
 97             mid=(l+r)/2;
 98             if (check(mid)){
 99                 ans=mid;
100                 l=mid+eps;
101             }
102             else r=mid-eps;
103         }
104         printf("%.6f\n",ans);
105     }
106     return 0;
107 }
poj3525

4.poj3384 Feng Shui

传送:http://poj.org/problem?id=3384

题意:给定两个同样大小的圆放置在多边形内(可以与多边形相切,两圆可以重叠),尽可能大的覆盖多边形面积,问两圆圆心。

分析:用半平面交将多边形的每条边一起向“内”推进R,得到新的多边形,然后求多边形的最远两点。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const double eps=1e-8;
 7 const int maxn=110;
 8 inline double sqr(double x){return x*x;}
 9 int n; double r;
10 int sgn(double x){
11     if (fabs(x)<eps) return 0;
12     if (x<0) return -1;
13     return 1;
14 }
15 struct point{
16     double x,y;
17     point(){}
18     point(double _x,double _y):x(_x),y(_y){}
19     point operator -(const point &b)const{
20         return point(x-b.x,y-b.y);
21     }
22     double operator ^(const point &b)const{
23         return x*b.y-y*b.x;
24     }
25 };
26 struct line{
27     point s,e;
28     double k; //斜率 
29     line(){}
30     line(point _s,point _e):s(_s),e(_e){k=atan2(e.y-s.y,e.x-s.x);}
31     point operator &(const line &b)const{ //求两直线交点
32         point res=s;
33         double t=((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
34         res.x+=(e.x-s.x)*t; res.y+=(e.y-s.y)*t;
35         return res;
36     }
37 };
38 point p[maxn]; //记录最初给的点集
39 line L[maxn]; //由最初的点集生成直线的集合
40 point pp[maxn]; //记录半平面交的结果的点集
41 //半平面交,直线的左边代表有效区域
42 bool HPIcmp(line a,line b){  //直线排序函数
43     if(sgn(a.k-b.k)!=0) return a.k<b.k; //斜率排序
44     //斜率相同我也不知道怎么办
45     return ((a.s-b.s)^(b.e-b.s))<0;
46 }
47 void HPI(line L[],int n,point res[],int &resn){ 
48 //line是半平面交的直线的集合 n是直线的条数 res是结果
49 //的点集 resn是点集里面点的个数
50     int tot=n;
51     sort(L,L+n,HPIcmp);
52     tot=1;
53     //去掉斜率重复的
54     for(int i=1;i<n;i++) if(sgn(L[i].k-L[i-1].k)!=0) L[tot++]=L[i];
55     int head,tail; line Q[maxn];  //双端队列 
56     Q[head=0]=L[0]; Q[tail=1]=L[1];
57     resn=0;
58     for(int i=2;i<tot;i++){
59         if(sgn((Q[tail].e-Q[tail].s)^(Q[tail-1].e-Q[tail-1].s))==0||
60         sgn((Q[head].e-Q[head].s)^(Q[head+1].e-Q[head+1].s))==0) return;
61         while(head<tail && (((Q[tail]&Q[tail-1])-L[i].s)^(L[i].e-L[i].s))>eps) tail--;
62         while(head<tail && (((Q[head]&Q[head+1])-L[i].s)^(L[i].e-L[i].s))>eps) head++;
63         Q[++tail]=L[i];
64     }
65     while(head<tail && (((Q[tail]&Q[tail-1])-Q[head].s)^(Q[head].e-Q[head].s))>eps) tail--;
66     while(head<tail && (((Q[head]&Q[head-1])-Q[tail].s)^(Q[tail].e-Q[tail].e))>eps) head++;
67     if(tail<=head+1) return;
68     for(int i=head;i<tail; i++) res[resn++]=Q[i]&Q[i+1];
69     if(head<tail-1) res[resn++]=Q[head]&Q[tail];
70 }
71 double dist(point a,point b){
72     return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
73 }
74 void change(point p1,point p2,point &a,point &b,double p){
75     double len=dist(p1,p2);
76     double dx=(p1.y-p2.y)*p/len,dy=(p2.x-p1.x)*p/len;
77     a.x=p1.x+dx;a.y=p1.y+dy;
78     b.x=p2.x+dx;b.y=p2.y+dy;
79 }
80 int main(){
81     while (cin >> n >> r){
82         for (int i=0;i<n;i++) cin >> p[i].x >> p[i].y;
83         reverse(p,p+n);
84         for (int i=0;i<n;i++){
85             point a,b;
86             change(p[i],p[(i+1)%n],a,b,r);
87             L[i]=line(a,b);
88         }
89         int resn;
90         HPI(L,n,pp,resn); //resn等于0说明移多了
91         int res1=0,res2=0;
92         for (int i=0;i<resn;i++)
93             for (int j=i+1;j<resn;j++){
94                 if (dist(pp[i],pp[j])>dist(pp[res1],pp[res2])) res1=i,res2=j;
95             }
96         printf("%.5f %.5f %.5f %.5f\n",pp[res1].x,pp[res1].y,pp[res2].x,pp[res2].y);
97     }
98     return 0;
99 }
poj3384

5.poj2540 Hotter Colder

传送:http://poj.org/problem?id=2540

题意:在10×10的房间里,有一个点放有宝藏。从(0,0)开始,每次走一个点,告诉你距离宝藏更近or更远,每次输出宝藏可能所在区域的面积。

分析:半平面交解线性规划问题。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<string>
  6 using namespace std;
  7 const double eps=1e-8;
  8 const int maxn=110;
  9 int sgn(double x){
 10     if (fabs(x)<eps) return 0;
 11     if (x<0) return -1;
 12     return 1;
 13 }
 14 struct point{
 15     double x,y;
 16     point(){}
 17     point(double _x,double _y):x(_x),y(_y){}
 18     point operator +(const point &b)const{
 19         return point(x+b.x,y+b.y);
 20     }
 21     point operator -(const point &b)const{
 22         return point(x-b.x,y-b.y);
 23     }
 24     double operator ^(const point &b)const{
 25         return x*b.y-y*b.x;
 26     }
 27     point operator *(double k)const{
 28         return point(x*k,y*k);
 29     }
 30 };
 31 point pp[maxn];
 32 struct line{
 33     point p,v;
 34     double k;
 35     line(){}
 36     line(point a,point b):p(a),v(b){k=atan2(v.y,v.x);}
 37     bool operator <(const line &b)const{
 38         return k<b.k;
 39     }
 40 };
 41 line L[maxn],q[maxn];
 42 bool left(const line &l,const point &p){
 43     return (l.v^(p-l.p))>0;   //点在线的上方 
 44 }
 45 point pos(const line &a,const line &b){
 46     point x=a.p-b.p;
 47     double t=(b.v^x)/(a.v^b.v);
 48     return a.p+a.v*t;
 49 }
 50 int HalfplaneIntersection(line L[],int n,point poly[]){
 51     sort(L,L+n);
 52     int first,last;
 53     point *p=new point[n];
 54     line *q=new line[n];
 55     q[first=last=0] = L[0];
 56     for(int i=1;i<n;i++){
 57         while(first < last && !left(L[i],p[last-1])) last--;
 58         while(first < last && !left(L[i],p[first])) first++;
 59         q[++last] = L[i];
 60         if(fabs((q[last].v^q[last-1].v))<eps) {
 61             last--;
 62             if(left(q[last],L[i].p)) q[last] = L[i];
 63         }
 64         if(first<last) p[last-1]=pos(q[last-1],q[last]);
 65     }
 66     while(first<last && !left(q[first],p[last-1])) last--;
 67     if(last-first <=1) return 0;
 68     p[last]=pos(q[last],q[first]);
 69     int m=0;
 70     for(int i=first;i<=last;i++) poly[m++]=p[i];
 71     return m;
 72 }
 73 double dist(point a){
 74     return sqrt(a.x*a.x+a.y*a.y);
 75 }
 76 point normal(point b) {
 77     double len=dist(b);
 78     return point(-b.y/len,b.x/len);
 79 }
 80 double getarea(point p[],int n){
 81     double sum=0;
 82     for (int i=0;i<n;i++) sum+=(p[i]^(p[(i+1)%n]));
 83     return fabs(sum)/2;
 84 }
 85 int main(){
 86     L[0]=line(point(0,0),point(10,0)-point(0,0));
 87     L[1]=line(point(10,0),point(10,10)-point(10,0));
 88     L[2]=line(point(10,10),point(0,10)-point(10,10));
 89     L[3]=line(point(0,10),point(0,0)-point(0,10));
 90     int cnt=4;
 91     double x1=0,y1=0,x2,y2; string ch;
 92     int f=1;
 93     while (cin >> x2 >> y2 >> ch){
 94         point a=point((x1+x2)/2,(y1+y2)/2),b;
 95         if (!f){cout << "0.00\n";continue;}
 96         if (ch[0]=='H') b=normal(point(x1,y1)-point(x2,y2));  
 97         else if (ch[0]=='C') b=normal(point(x2,y2)-point(x1,y1));  
 98         else{cout << "0.00\n";f=0;continue;}
 99         L[cnt++]=line(a,b);
100         int xx=HalfplaneIntersection(L,cnt,pp);
101         if (xx==0){cout << "0.00\n";f=0;continue;}
102         else{
103             double ans=getarea(pp,xx);
104             printf("%.2f\n",ans);
105             if (sgn(ans)==0) f=0; 
106         }
107         x1=x2;y1=y2;
108     } 
109     return 0;
110 } 
poj2540
  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<string>
  6 using namespace std;
  7 const double eps=1e-8;
  8 const int maxn=110;
  9 inline double sqr(double x){return x*x;}
 10 int n; double r;
 11 int sgn(double x){
 12     if (fabs(x)<eps) return 0;
 13     if (x<0) return -1;
 14     return 1;
 15 }
 16 struct point{
 17     double x,y;
 18     point(){}
 19     point(double _x,double _y):x(_x),y(_y){}
 20     point operator -(const point &b)const{
 21         return point(x-b.x,y-b.y);
 22     }
 23     double operator ^(const point &b)const{
 24         return x*b.y-y*b.x;
 25     }
 26 };
 27 struct line{
 28     point s,e;
 29     double k; //斜率 
 30     line(){}
 31     line(point _s,point _e):s(_s),e(_e){k=atan2(e.y-s.y,e.x-s.x);}
 32     point operator &(const line &b)const{ //求两直线交点
 33         point res=s;
 34         double t=((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
 35         res.x+=(e.x-s.x)*t; res.y+=(e.y-s.y)*t;
 36         return res;
 37     }
 38 };
 39 line L[maxn]; //由最初的点集生成直线的集合
 40 point pp[maxn]; //记录半平面交的结果的点集
 41 //半平面交,直线的左边代表有效区域
 42 bool HPIcmp(line a,line b){  //直线排序函数
 43     if(sgn(a.k-b.k)!=0) return a.k<b.k; //斜率排序
 44     return ((a.s-b.s)^(b.e-b.s))<0;
 45 }
 46 void HPI(line L[],int n,point res[],int &resn){ 
 47     int tot=n;
 48     sort(L,L+n,HPIcmp);
 49     tot=1;
 50     //去掉斜率重复的
 51     for(int i=1;i<n;i++) if(sgn(L[i].k-L[i-1].k)!=0) L[tot++]=L[i];
 52     int head,tail; line Q[maxn];  //双端队列 
 53     Q[head=0]=L[0]; Q[tail=1]=L[1];
 54     resn=0;
 55     for(int i=2;i<tot;i++){
 56         if(sgn((Q[tail].e-Q[tail].s)^(Q[tail-1].e-Q[tail-1].s))==0||
 57         sgn((Q[head].e-Q[head].s)^(Q[head+1].e-Q[head+1].s))==0) return;
 58         while(head<tail && (((Q[tail]&Q[tail-1])-L[i].s)^(L[i].e-L[i].s))>eps) tail--;
 59         while(head<tail && (((Q[head]&Q[head+1])-L[i].s)^(L[i].e-L[i].s))>eps) head++;
 60         Q[++tail]=L[i];
 61     }
 62     while(head<tail && (((Q[tail]&Q[tail-1])-Q[head].s)^(Q[head].e-Q[head].s))>eps) tail--;
 63     while(head<tail && (((Q[head]&Q[head-1])-Q[tail].s)^(Q[tail].e-Q[tail].e))>eps) head++;
 64     if(tail<=head+1) return;
 65     for(int i=head;i<tail; i++) res[resn++]=Q[i]&Q[i+1];
 66     if(head<tail-1) res[resn++]=Q[head]&Q[tail];
 67 }
 68 double getarea(point p[],int n){
 69     double sum=0;
 70     for (int i=0;i<n;i++) sum+=(p[i]^p[(i+1)%n]);
 71     return fabs(sum)/2;
 72 }
 73 // 将向量 AB 逆时针旋转角度A
 74 inline point Revolve(double cosA, double sinA, point A, point B){ 
 75     point B_;
 76     B_.x = (B.x - A.x) * cosA - (B.y - A.y) * sinA + A.x;
 77     B_.y = (B.x - A.x) * sinA + (B.y - A.y) * cosA + A.y;
 78     return B_;
 79 }
 80 int main(){
 81     L[0]=line(point(0,0),point(10,0));
 82     L[1]=line(point(10,0),point(10,10));
 83     L[2]=line(point(10,10),point(0,10));
 84     L[3]=line(point(0,10),point(0,0));
 85     int cnt=4;
 86     double x1=0,y1=0,x2,y2; string ch;
 87     int f=1;
 88     while (cin >> x2 >> y2 >> ch){
 89         point a=point((x1+x2)/2,(y1+y2)/2),b;
 90         int resn;
 91         if (!f){cout << "0.00\n";continue;}
 92         if (ch[0]=='C'){
 93             b=Revolve(0,1,a,point(x2,y2));
 94         }
 95         else if (ch[0]=='H'){
 96             b=Revolve(0,-1,a,point(x2,y2));
 97         }
 98         else{cout << "0.00\n";f=0;continue;}
 99         L[cnt++]=line(a,b);
100         HPI(L,cnt,pp,resn);
101         if (resn==0){cout << "0.00\n";f=0;continue;} 
102         else{
103             double area=getarea(pp,resn);
104             printf("%.2f\n",area);
105         }
106         x1=x2;y1=y2;
107     } 
108     return 0;
109 } 
poj2540(2)

转载于:https://www.cnblogs.com/changer-qyz/p/9785988.html

相关文章:

设计模式之状态模块加观察者模式

背景&#xff1a; 用户操作鼠标&#xff0c;涉及的动作有左击、右击、双击。每种动作对应一种状态&#xff0c;状态的切换对应着不同的鼠标点击事件。 类图&#xff1a; 状态接口类&#xff1a; /*** 状态接口**/ public interface State {public void change(); } 鼠标移入类&…

objectdatasource中delete的尴尬。

这里用的是listview和objectdatasource。本来是为了省力直接用了objectdatasource&#xff0c;这可倒好为了一个不知名的问题折腾了半天。首先&#xff0c;本来用objectdatasource&#xff0c;里面的各种method&#xff0c;比如delete&#xff0c;update等等&#xff0c;对应的…

1039 Course List for Student

1. 此题必须采用vectorhash的策略&#xff0c;否则最后一个用例超时&#xff0c;定义一个vector类型的数组&#xff0c;长度由名字的最大范围决定 vector<int> stus[26*26*26*10]; 2. 起初我定义了结构体&#xff0c;里面用一个字符串存放学生的名字&#xff0c;vector…

《编程匠艺》读书笔记

《编程匠艺》读书笔记之一 《编程匠艺》读书笔记之二 《编程匠艺》读书笔记之三 《编程匠艺》读书笔记之四 《编程匠艺》读书笔记之五 《编程匠艺》读书笔记之六 《编程匠艺》读书笔记之七 《编程匠艺》读书笔记之八 《编程匠艺》读书笔记之九 《编程匠艺》读书笔记之十 《编程…

【转】C语言的memset函数

http://vip.6to23.com/tenax/clib/string/memset.htmlhttp://hi.baidu.com/longchengjiang/blog/item/32c0e243acb8191772f05d29.htmlhttp://www.cnblogs.com/xray2005/archive/2009/07/07/1518288.html 原型&#xff1a;extern void *memset(void *buffer, int c, int count);…

一个6年iOS程序员的工作感悟,送给还在迷茫的你

前言 每一个开发者&#xff0c;都有一段不愿提起的经历&#xff0c;很多年前&#xff0c;刚刚从大学毕业的时候&#xff0c;很多公司来校招。其中最烂俗的一个面试问题是&#xff1a;“你希望你之后三到五年的发展是什么&#xff1f;”。我当时的标准回答是&#xff08;原话&am…

1063 Set Similarity

1. 这题需要利用set容器的去重功能&#xff0c;因此使用set来存放每一组的数据。 2. 起初我的计算相似度的函数是这样设计的&#xff1a;传入set1和set2&#xff0c;声明一个set3&#xff0c;将set1中的数据全部插入set3中&#xff0c;再声明一个重复元素个数same_n&#xff0…

Volume是如何工作的

在这篇文章中&#xff0c;我会尽最大的努力来解释Volume是如何工作的&#xff0c;并展示一些最佳实践。这篇文章主要是针对那些对Volume不了解的Docker用户&#xff0c;当然有经验的用户也可以通过本文了解一些Volume的细节。想要了解Docker Volume&#xff0c;首先我们需要知道…

使用 TFDConnection 的 pooled 连接池

从开始看到这个属性&#xff0c;就一直认为他可以提供一个连接池管理功能&#xff0c; 苦于文档资料太少&#xff0c; 甚至在帮助中对该属性的使用都没有任何介绍&#xff0c;如果你搜索百度&#xff0c;也会发现基本没资料。 最后终于在其官方网站看到了其完整相关的英文资料&…

Java与UML交互图

Java与UML交互图 前面我们主要讨论的是UML类图&#xff0c;下面我们要讨论的是另一种UML图——交互图&#xff08;Interaction Diagram&#xff09;。交互图描述的是一组对象之间的交互过程&#xff0c;或者说&#xff0c;这里我们实际上要回答这样一个问题&#xff1a;“方法调…

1054 The Dominant Color

1. 此题用到了map<string,int>将输入的颜色(long long也存不下&#xff0c;只好作为string存入)的次数记录&#xff0c;看来默认一个没出现过的string对应的int是0。因此记次数的时候 if(mp[str])mp[str] 1;//如果不是第一次出现&#xff0c;出现次数1 else mp[str] …

通过sqlserver日志恢复误删除的数据

通过sqlserver日志恢复误删除的数据 原文:通过sqlserver日志恢复误删除的数据如果你已经急的焦头烂额&#xff0c;看到这篇文章的时候&#xff0c;请你换个坐姿&#xff0c;深呼吸几次&#xff0c;静下心来将这篇文章读完&#xff0c;也许你的问题迎刃而解。 我遇到的情况是这样…

关于在phpStudy环境下,windows cmd中 php不是内部命令问题

首先查看system32是否加入系统变量 其次要把当前运行的php版本的路径加入到系统变量中去&#xff0c;path中&#xff0c; 一定要是这个样子的&#xff1b; D:\phpStudy\php\php-5.6.27-nts 不然没有什么用。 这样在phpstorm中以及cmd中都可以使用php命令了。

如何用javascript控制上传文件的大小

以下是引用片段&#xff1a;<form nameMyform οnsubmit"return CheckFileSize()"> <input typefile namephoto><br/> <input typesubmit valuesubmit></form> <SCRIPT LANGUAGE"JavaScri…

1071 Speech Patterns 需再做

1. alphanumerical 的意思是字母数字混合编制的&#xff0c;也就是一句话中被认为是“单词”的组成成分的有数字和字母。这也是为什么例句中can1不被认为是can。 由于这道题对大小写不敏感&#xff0c;不妨在读入后&#xff0c;把大写字母全部改成小写 //大写换小写 for(int…

IOS类似9.png

图形用户界面中的图形有两种实现方式&#xff0c;一种是用代码画出来&#xff0c;比如Quartz 2D技术&#xff0c;狠一点有OpenGL ES&#xff0c;另一种则是使用图片。 代码画的方式比较耗费程序员脑力,CPU或GPU; 图片则耗费磁盘空间,会增加app的体积.一般的app我们会偏重于使用…

Shell 编程

Shell 是一个用 C 语言编写的程序&#xff0c;通过 Shell 用户可以访问操作系统内核服务。它类似于 DOS 下的 command 和后来的 cmd.exe。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。Shell script 是一种为 shell 编写的脚本程序。Shell 编程一般指 shell 脚本编…

表现层框架Struts/Tapestry/JSF架构比较 [转]

http://www.jdon.com/artichect/sjt.htm Struts/Tapestry/JSF是目前J2EE表现层新老组合的框架技术。从诞生时间上看&#xff0c;Struts应该比较早&#xff0c;使用得非常广泛&#xff0c;Tapestry 3.0逐渐引起广泛的重视&#xff0c;正当Tapestry即将大显身手时期&#xff0c;S…

1022 Digital Library

1. 关键数据结构 map<string,vector<string> > mp[6] 其中mp[1]代表从书名映射到id&#xff08;id可能无&#xff0c;可能不止一个&#xff0c;所以要用vector&#xff09;&#xff0c;mp[2]是从作者映射到id……mp[5]代表从year映射到id。 2. 卡住的第一个地方是…

event.keyCode用法及列表

用户名&#xff1a;<input type"text" id"UserAccount" onKeyPress"JumpByEnter(UserPwd)" />密码&#xff1a;<input name"UserPwd" type"password" onKeyPress"IsEnterKeyPress()"> JavaScript&…

网络游戏术语(转)

转自&#xff1a;https://site.douban.com/149989/widget/notes/8053161/note/231207595/ AC – Armor Class&#xff0c;盔甲等级、级别Account – 账号&#xff0c;与密码Password相对Add – 一只玩家加入到组队中&#xff0c;如果请求别人组队&#xff0c;可说Add me pls.AO…

vim的一些快捷键,备忘

vim的一些快捷键&#xff0c;备忘 快捷键 作用ctrlg 显示当前行的信息G 跳到某一行:%s/oldtxt/newtxt/g …

1051 Pop Sequence(两种双指针思路)

目录 思路一&#xff1a;以入栈序列为总纲&#xff0c;2层循环&#xff0c;外for内while 思路二&#xff1a;一层while 思路一&#xff1a;以入栈序列为总纲&#xff0c;2层循环&#xff0c;外for内while 注意弹栈之前要判空&#xff0c;不然会出现段错误。 AC代码 #inclu…

iOS底层原理 - 常驻线程

iOS底层原理 - 常驻线程 在 AFN 2.0 时代&#xff0c;会经常看到 AFN 创建一个常驻线程的方式&#xff1a; 0️⃣ AFN 2.0 时代的常驻线程 (NSThread *)networkRequestThread {static NSThread *_networkRequestThread nil;static dispatch_once_t oncePredicate;dispatch_on…

A monad tutorial for Clojure programmers (part 3)

Before moving on to the more advanced aspects of monads, let’s recapitulate what defines a monad (see part 1 and part 2 for explanations): A data structure that represents the result of a computation, or the computation itself. We haven’t seen an example…

Flex精华摘要--使用AS脚本

在MXML文件中实现ActionScript逻辑的几种方法&#xff1a;最简单的方法&#xff0c;在一个MXML文件中通过组件的事件直接书写简单的逻辑控制&#xff0c;但是并不推荐。 <?xml version"1.0" encoding"utf-8"?> <mx:Application xmlns:mx"h…

(C++)自定义链表并写入

确定链表节点的组成&#xff0c;一般由数据和指针构成 struct node{int data;//数据域node* next;//指针域 }; 使用new运算符为节点分配内存空间 node* p new node; 编写创建列表函数&#xff0c;参数为链表的长度(从用户输入读入)&#xff0c;返回值为创建的列表的头指针…

Unicode转义(\uXXXX)的编码和解码

在涉及Web前端开发时, 有时会遇到\uXXXX格式表示的字符, 其中XXXX是16进制数字的字符串表示形式, 在js中这个叫Unicode转义字符, 和\n \r同属于转义字符. 在其他语言中也有类似的, 可能还有其它变形的格式. 多数时候遇到需要解码的情况多点, 所以会先介绍解码decode, 后介绍…

BZOJ 2004 [Hnoi2010]Bus 公交线路

题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id2004 题解 状压dp&#xff0c;记f[i][S]f[i][S]f[i][S]表示[1,i−p][1,i-p][1,i−p]的车都被安排好了&#xff0c;而[i−p1,i][i-p1,i][i−p1,i]的车中&#xff0c;SSS中有111的位置都安排有车停&#xff0c;并且恰…

【转载】C语言编译全过程

今天在blog.chinaunix.net/u3博客看到一篇关于语言编译过程的文章&#xff0c;觉得精简&#xff0c;清晰所以摘录下来我的blog。作为一个程序员了解编译过程对程序的编写也很有帮助。下面是博文的内容&#xff1a;编译的概念&#xff1a;编译程序读取源程序&#xff08;字符流&…