生活随笔
收集整理的這篇文章主要介紹了
P4196 [CQOI2006]凸多边形 /【模板】半平面交
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
P4196 [CQOI2006]凸多邊形 /【模板】半平面交
本來是個板子題,而且我這個板子之前在POJ寫過一些題目了,但是這里一直讓我RE。
后來解決辦法竟然是:先讀入第一個多邊形不加邊(存下來),然后去讀其他多邊形,邊讀邊加入。
最后加入第一個多邊形,這樣就過了???好像是一樣的啊…
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>using namespace std
;const double pi
= acos(-1.0);
const double eps
= 1e-5;
const double inf
= 1e100;int Sgn(double x
) {return x
< -eps
? -1 : x
> eps
;
}struct Vector
{double x
, y
;bool operator < (Vector
&a
) const {return x
< a
.x
;}void print() {printf("%f %f\n", x
, y
);}void read() {scanf("%lf %lf", &x
, &y
);}Vector(double _x
= 0, double _y
= 0) : x(_x
), y(_y
) {}double mod() {return sqrt(x
* x
+ y
* y
);}double mod2() {return x
* x
+ y
* y
;}Vector
operator + (const Vector
&a
) {return Vector(x
+ a
.x
, y
+ a
.y
);}Vector
operator - (const Vector
&a
) {return Vector(x
- a
.x
, y
- a
.y
);}double operator * (const Vector
&a
) {return x
* a
.x
+ y
* a
.y
;}double operator ^ (const Vector
&a
) {return x
* a
.y
- y
* a
.x
;}Vector
Rotate(double angle
) {return Vector(x
* cos(angle
) - y
* sin(angle
), x
* sin(angle
) + y
* cos(angle
));}Vector
operator << (const double &a
) {return Vector(x
* a
, y
* a
);}Vector
operator >> (const double &a
) {return Vector(x
/ a
, y
/ a
);}bool operator == (const Vector
& a
) {return (Sgn(x
- a
.x
) == 0) && (Sgn(y
- a
.y
) == 0);}
};typedef Vector Point
;double Dis_pp(Point a
, Point b
) {return sqrt((a
- b
) * (a
- b
));
}double Angle(Vector a
, Vector b
) {double ans
= atan2(a
^ b
, a
* b
);return ans
< 0 ? ans
+ 2 * pi
: ans
;
}double To_lefttest(Point a
, Point b
, Point c
) {return (b
- a
) ^(c
- a
);
}int Toleft_test(Point a
, Point b
, Point c
) {return Sgn((b
- a
) ^ (c
- a
));
}struct Line
{Point st
, ed
;Line(Point _st
= Point(0, 0), Point _ed
= Point(0, 0)) : st(_st
), ed(_ed
) {}bool operator < (const Line
&t
) {return st
.x
< t
.st
.x
;}void read() {scanf("%lf %lf %lf %lf", &st
.x
, &st
.y
, &ed
.x
, &ed
.y
);}
};bool Parallel(Line a
, Line b
) {return Sgn((a
.st
- a
.ed
) ^ (b
.st
- b
.ed
)) == 0;
}bool Is_cross(Line a
, Line b
) {return Toleft_test(a
.st
, a
.ed
, b
.st
) * Toleft_test(a
.st
, a
.ed
, b
.ed
) <= 0 && Toleft_test(b
.st
, b
.ed
, a
.st
) * Toleft_test(b
.st
, b
.ed
, a
.ed
) <= 0;
}Point
Cross_point(Line a
, Line b
) {if(!Is_cross(a
, b
)) {return Point(inf
, inf
);}else {double a1
= fabs(To_lefttest(a
.st
, a
.ed
, b
.st
)), a2
= fabs(To_lefttest(a
.st
, a
.ed
, b
.ed
));return ((b
.st
<< a2
) + (b
.ed
<< a1
)) >> (a1
+ a2
);}
}Point
Intersect_point(Line a
, Line b
) {double a1
= a
.st
.y
- a
.ed
.y
, b1
= a
.ed
.x
- a
.st
.x
, c1
= a
.st
.x
* a
.ed
.y
- a
.ed
.x
* a
.st
.y
;double a2
= b
.st
.y
- b
.ed
.y
, b2
= b
.ed
.x
- b
.st
.x
, c2
= b
.st
.x
* b
.ed
.y
- b
.ed
.x
* b
.st
.y
;return Point((c1
* b2
- c2
* b1
) / (a2
* b1
- a1
* b2
), (a2
* c1
- a1
* c2
) / (a1
* b2
- a2
* b1
));
}Point
Shadow(Line a
, Point b
) {Point dir
= a
.ed
- a
.st
;return a
.st
+ (dir
<< (((b
- a
.st
) * dir
) / dir
.mod2()));
}Point
Reflect(Line a
, Point b
) {return (Shadow(a
, b
) << 2) - b
;
}bool inmid(double a
, double b
, double x
) {if(a
> b
) swap(a
, b
);return Sgn(x
- a
) >= 0 && Sgn(b
- x
) >= 0;
}bool Point_in_line(Line a
, Point b
) {if(Toleft_test(a
.st
, a
.ed
, b
) != 0) return false;return inmid(a
.st
.x
, a
.ed
.x
, b
.x
) && inmid(a
.st
.y
, a
.ed
.y
, b
.y
);
}double Dis_lp(Line a
, Point b
) {Point h
= Shadow(a
, b
);if(Point_in_line(a
, h
)) {return Dis_pp(h
, b
);}return min(Dis_pp(a
.st
, b
), Dis_pp(a
.ed
, b
));
}
double Area(vector
<Point
> p
, int n
) {double ans
= 0;for(int i
= 0; i
< n
; i
++) {ans
+= p
[i
] ^ p
[(i
+ 1) % n
];}return 0.5 * ans
;
}double len(vector
<Point
> p
, int n
) {double ans
= 0;for(int i
= 0; i
< n
; i
++) {ans
+= Dis_pp(p
[i
], p
[(i
+ 1) % n
]);}return ans
;
}bool Is_convex(Point
*a
, int n
) {bool flag
[3] = {0, 0, 0};for(int i
= 0; i
< n
; i
++) {flag
[Sgn(To_lefttest(a
[i
], a
[(i
+ 1) % n
], a
[(i
+ 2) % n
])) + 1] = true;if(flag
[0] && flag
[2]) return false;}return true;
}Point p0
;bool cmp_graham(Point a
, Point b
) {int flag
= Toleft_test(p0
, a
, b
);return flag
== 0 ? Dis_pp(p0
, a
) < Dis_pp(p0
, b
) : flag
> 0;
}vector
<Point
> Graham(vector
<Point
> &a
, int n
) {p0
= a
[0];for(int i
= 0; i
< n
; i
++) {if(a
[i
].y
< p0
.y
|| (a
[i
].y
== p0
.y
&& a
[i
].x
< p0
.x
)) {p0
= a
[i
];}}vector
<Point
> ans
;sort(a
.begin(), a
.end(), cmp_graham
);if(n
== 1) {ans
.push_back(a
[0]);return ans
;}if(n
== 2) {ans
.push_back(a
[0]);ans
.push_back(a
[1]);return ans
;}ans
.push_back(a
[0]);ans
.push_back(a
[1]);int sz
= 2;for(int i
= 2; i
< n
; i
++) {while(sz
> 1 && To_lefttest(ans
[sz
- 2], ans
[sz
- 1], a
[i
]) <= 0) {ans
.pop_back();sz
--;}ans
.push_back(a
[i
]);sz
++;}return ans
;
}bool cmp_andrew(Point a
, Point b
) {if(Sgn(a
.x
- b
.x
) == 0) return a
.y
< b
.y
;return a
.x
< b
.x
;
}vector
<Point
> Andrew(vector
<Point
> &a
, int n
) {sort(a
.begin(), a
.end(), cmp_andrew
);int p1
= 0, p2
;vector
<Point
> ans
;for(int i
= 0; i
< n
; i
++) {while(p1
> 1 && Toleft_test(ans
[p1
- 2], ans
[p1
- 1], a
[i
]) <= 0) ans
.pop_back(), p1
--;ans
.push_back(a
[i
]), p1
++;}p2
= p1
;for(int i
= n
- 2; i
>= 0; i
--) {while(p2
> p1
&& Toleft_test(ans
[p2
- 2], ans
[p2
- 1], a
[i
]) <= 0) ans
.pop_back(), p2
--;ans
.push_back(a
[i
]), p2
++;}return ans
;
}double Get_angle(Line a
) {return atan2(a
.ed
.y
- a
.st
.y
, a
.ed
.x
- a
.st
.x
);
}bool cmp_Half_lane_intersection(Line a
, Line b
) {Vector va
= a
.ed
- a
.st
, vb
= b
.ed
- b
.st
;double A
= Get_angle(va
), B
= Get_angle(vb
);if (Sgn(A
- B
) == 0) return Sgn(((va
) ^ (b
.ed
- a
.st
))) != -1;return Sgn(A
- B
) == -1;
}bool On_right(Line a
, Line b
, Line c
) {Point o
= Intersect_point(b
, c
);if (Sgn((a
.ed
- a
.st
) ^ (o
- a
.st
)) < 0) return true;return false;
}const int N
= 2e3 + 10;Line que
[N
];double Half_lane_intersection(vector
<Line
> a
) {sort(a
.begin(), a
.end(), cmp_Half_lane_intersection
);int head
= 0, tail
= 0, cnt
= 0, n
= a
.size();for(int i
= 0; i
< n
- 1; i
++) {if(Sgn(Get_angle(a
[i
]) - Get_angle(a
[i
+ 1])) == 0) continue;a
[cnt
++] = a
[i
];}a
[cnt
++] = a
[n
- 1];for(int i
= 0; i
< cnt
; i
++) {while(tail
- head
> 1 && On_right(a
[i
], que
[tail
- 1], que
[tail
- 2])) tail
--;while(tail
- head
> 1 && On_right(a
[i
], que
[head
], que
[head
+ 1])) head
++;que
[tail
++] = a
[i
];}while(tail
- head
> 1 && On_right(que
[head
], que
[tail
- 1], que
[tail
- 2])) tail
--;while(tail
- head
> 1 && On_right(que
[tail
- 1], que
[head
], que
[head
+ 1])) head
++;n
= tail
- head
;if(n
< 3) return 0;vector
<Point
> ans
;for(int i
= head
; i
< tail
; i
++) {ans
.push_back(Intersect_point(que
[i
], que
[(i
- head
+ 1) % n
+ head
]));}return fabs(Area(ans
, ans
.size()));
}int main() {vector
<Line
> a
;int T
;scanf("%d", &T
);int m
;scanf("%d", &m
);vector
<Point
> b
;for(int i
= 0; i
< m
; i
++) {Point temp
;temp
.read();b
.push_back(temp
);}for(int cas
= 2; cas
<= T
; cas
++) {int n
;scanf("%d", &n
);vector
<Point
> p
;for(int i
= 0; i
< n
; i
++) {Point temp
;temp
.read();p
.push_back(temp
);}for(int i
= 0; i
< n
; i
++) {a
.push_back(Line(p
[i
], p
[(i
+ 1) % n
]));}}for(int i
= 0; i
< m
; i
++) {a
.push_back(Line(b
[i
], b
[(i
+ 1) % m
]));}printf("%.3f\n", Half_lane_intersection(a
));return 0;
}
總結
以上是生活随笔為你收集整理的P4196 [CQOI2006]凸多边形 /【模板】半平面交的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。