点,线,面,形基本关系,点积叉积的理解

poj2318 TOYS

/****************************\* @prob: poj2318 TOYS      ** @auth: Wang Junji        ** @stat: Accepted.         ** @date: June. 25th, 2012  ** @memo: 点和直线位置关系    *
\****************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>const int maxN = 5010;
int cnt[maxN], lower[maxN], upper[maxN], n, m, X0, Y0, X1, Y1;inline int Find(int x, int y)
{int L = 0, R = n;while (L < R){int Mid = (L + R) >> 1;double __x = (upper[Mid] - lower[Mid]) / double(Y1 - Y0) * (y - Y0) + lower[Mid];if (__x < x) L = Mid + 1;else R = Mid;} /* while */return R - 1;
} /* Find */int main()
{freopen("toys.in" , "r", stdin );freopen("toys.out", "w", stdout);while (~scanf("%d%d%d%d%d%d", &n, &m, &X0, &Y1, &X1, &Y0) && n){++n; upper[0] = lower[0] = X0;for (int i = 1; i < n; ++i)scanf("%d%d", upper + i, lower + i);lower[n] = upper[n] = X1;memset(cnt, 0, sizeof cnt);while (m--){int x, y;scanf("%d%d", &x, &y);++cnt[Find(x, y)];} /* while */for (int i = 0; i < n; ++i)printf("%d: %d\n", i, cnt[i]);puts("");} /* while */return 0;
} /* main *//*用二分查找每个玩具所对应的分区即可。*/

poj2398 Toy Storage

/*******************************\* @prob: poj2398 Toy Storage  ** @auth: Wang Junji           ** @stat: Accepted.            ** @date: June. 25th, 2012     ** @memo: 点和直线位置关系       *
\*******************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>const int maxN = 1010;
int has[maxN], cnt[maxN], lower[maxN], upper[maxN], n, m, X0, Y0, X1, Y1;inline int Find(int x, int y)
{int L = 0, R = n;while (L < R){int Mid = (L + R) >> 1;double __x = (upper[Mid] - lower[Mid]) / double(Y1 - Y0) * (y - Y0) + lower[Mid];if (__x < x) L = Mid + 1;else R = Mid;} /* while */return R - 1;
} /* Find */int main()
{freopen("Toy_Storage.in" , "r", stdin );freopen("Toy_Storage.out", "w", stdout);while (~scanf("%d%d%d%d%d%d", &n, &m, &X0, &Y1, &X1, &Y0) && n){++n; upper[0] = lower[0] = X0;for (int i = 1; i < n; ++i)scanf("%d%d", upper + i, lower + i);lower[n] = upper[n] = X1;std::sort(lower, lower + n);std::sort(upper, upper + n);memset(cnt, 0, sizeof cnt);memset(has, 0, sizeof has);while (m--){int x, y;scanf("%d%d", &x, &y);++has[Find(x, y)];} /* while */puts("Box");for (int i = 0; i < n; ++i) ++cnt[has[i]];for (int i = 1; i < n; ++i)if (cnt[i]) printf("%d: %d\n", i, cnt[i]);} /* while */return 0;
} /* main *//*用二分查找每个玩具所对应的分区即可。*/

视野动态规划

poj1556 The Doors

/*****************************\* @prob: poj1556 The Doors  ** @auth: Wang Junji         ** @stat: Accepted.          ** @date: June. 25th. 2012   ** @memo: 视野动态规划        *
\*****************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>const int maxN = 110;
const double INF = 1e198, zero = 1e-8;struct vec
{double x, y; vec() {} /* vec */vec(const double& x, const double& y): x(x), y(y) {} /* vec */vec(const vec& b): x(b.x), y(b.y) {} /* vec */vec operator-(const vec& b) const{return vec(x - b.x, y - b.y);}/* operator- */double operator*(const vec& b) const{return x * b.y - y * b.x;}/* operator* */vec lwr() const {return vec(x, y - 1);} /* lwr */vec upr() const {return vec(x, y + 1);} /* upr */
} p[maxN][4]; int n; double d[maxN][4];template <typename _Tp>
inline _Tp& gmax(_Tp& a, const _Tp& b)
{return a > b ? a : (a = b);}
/* gmax */template <typename _Tp>
inline _Tp& gmin(_Tp& a, const _Tp& b)
{return a < b ? a : (a = b);}
/* gmin */template <typename _Tp> inline _Tp sqr(const _Tp& x) {return x * x;} /* sqr */inline
bool check(const vec& lwr, const vec& upr,const vec& st , const vec& ed)
{if (st.x - ed.x > -zero) return false;if ((ed  - st) * (lwr - st) > zero) return false;if ((upr - st) * (ed  - st) > zero) return false;return true;
} /* check */inline double dist(const vec& a, const vec& b)
{return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}
/* dist */inline
void work(const double& val,const vec& lwr,const vec& upr,const vec& st,const int& i)
{if (val - INF > -zero) return;if (d[n][0] - 10 < zero) return;if (i == n && check(lwr, upr, st, p[n][0]))gmin(d[n][0], val + dist(st, p[n][0]));for (int j = 0; j < 4; ++j)if (check(lwr, upr, st, p[i][j]))gmin(d[i][j], val + dist(st, p[i][j]));vec __lwr(lwr), __upr(upr);bool ch_lwr = check(lwr, upr, st, p[i][0]),ch_upr = check(lwr, upr, st, p[i][1]);if (ch_lwr) __lwr = p[i][0];if (ch_upr) __upr = p[i][1];if (__lwr * __upr > zero && (ch_lwr || ch_upr))work(val, __lwr, __upr, st, i + 1);__lwr = lwr, __upr = upr;ch_lwr = check(lwr, upr, st, p[i][2]);ch_upr = check(lwr, upr, st, p[i][3]);if (ch_lwr) __lwr = p[i][2];if (ch_upr) __upr = p[i][3];if (__lwr * __upr > zero && (ch_lwr || ch_upr))work(val, __lwr, __upr, st, i + 1);return;
} /* work */int main()
{freopen("door.in" , "r", stdin );freopen("door.out", "w", stdout);while (~scanf("%d", &n) && ~n){p[0][0] = vec(0., 5.); ++n;for (int i = 1; i < n; ++i){double x, y0, y1, y2, y3;scanf("%lf%lf%lf%lf%lf", &x, &y0, &y1, &y2, &y3);p[i][0] = vec(x, y0);p[i][1] = vec(x, y1);p[i][2] = vec(x, y2);p[i][3] = vec(x, y3);d[i][0] = d[i][1] = d[i][2] = d[i][3] = INF;} /* for */p[n][0] = vec(10., 5.); d[n][0] = INF;work(0, p[0][0].lwr(), p[0][0].upr(), p[0][0], 1);for (int i = 1; i < n; ++i)for (int j = 0; j < 4; ++j)work(d[i][j], p[i][j].lwr(), p[i][j].upr(), p[i][j], i + 1);printf("%.2lf\n", d[n][0]);} /* while */return 0;
} /* main *//*维护视野的上界和下界,然后依次松弛每个点即可。*/

凸包、旋转卡壳

UVa681 Convex Hull Finding

/**************************************\* @prob: UVa681 Convex Hull Finding  ** @auth: Wang Junji                  ** @stat: Accepted.                   ** @date: June. 26th, 2012            ** @memo: 凸包                        *
\**************************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>int const maxN = 520;
struct vec
{int x, y; vec() {} /* vec */ vec(int x, int y): x(x), y(y) {} /* vec */vec operator-(const vec& b) const {return vec(x - b.x,  y - b.y);} /* operator- */int operator*(const vec& b) const {return     x * b.y - y * b.x; } /* operator- */
} p[maxN], res[maxN];
int n, T;inline vec const*
Granham(vec const* const __fir, vec const* const __la, vec* res)
{vec* tmp = res + 1; vec const* fir = __fir;if (fir == __la) return res;*res++ = *fir++; if (fir == __la) return res;*res++ = *fir++; if (fir == __la) return res;for (; fir != __la; *res++ = *fir++)while (res != tmp && (fir[0] - res[-1]) * (res[-1] - res[-2]) >= 0)--res;tmp = res; *res++ = __la[-2];for (fir = __la - 2; fir-- != __fir; *res++ = *fir)while (res != tmp && (fir[0] - res[-1]) * (res[-1] - res[-2]) >= 0)--res;return res;
} /* Granham */inline bool cmp(vec const& a, vec const& b)
{return a.y < b.y || (a.y == b.y && a.x < b.x);}
/* cmp */int main()
{freopen("Convex_Hull.in" , "r", stdin );freopen("Convex_Hull.out", "w", stdout);for (scanf("%d", &T), printf("%d\n", T); T--; ~scanf("\n-1") && puts("-1")){scanf("%d", &n);for (int i = 0; i < n; ++i)scanf("%d%d", &p[i].x, &p[i].y);std::sort(p, p + n, cmp);n = Granham(p, p + n, res) - res;printf("%d\n", n);for (int i = 0; i < n; ++i)printf("%d %d\n", res[i].x, res[i].y);} /* for */return 0;
} /* main *//*凸包的模板题,不再多说。*/

poj2187 Beauty Contest

/**********************************\* @prob: poj2187 Beauty Contest  ** @auth: Wang Junji              ** @stat: Accepted.               ** @date: June. 28th, 2012        ** @memo: 旋转卡壳                 *
\**********************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>const int maxN = 50010;struct vec
{int x, y; vec() {} /* vec */ vec(int x, int y): x(x), y(y) {} /* vec */vec operator-(const vec& b) const {return vec(x - b.x, y - b.y);} /* operator- */int operator*(const vec& b) const {return x * b.y - y * b.x;} /* operator* */int sqrabs() const {return x * x + y * y;}
} p[maxN], res[maxN]; int n;inline int& gmax(int& a, const int& b) {return a > b ? a : (a = b);} /* gmax */inline bool cmp(const vec& a, const vec& b)
{return a.y < b.y || (a.y == b.y && a.x < b.x);}
/* cmp */inline const vec*
Granham(const vec* const __fir, const vec* const __la, vec* res)
{const vec* fir = __fir;const vec* tmp = res + 1;for (*res++ = *fir++, *res++ = *fir++; fir != __la; *res++ = *fir++)while (res != tmp && (fir[0] - res[-1]) * (res[-1] - res[-2]) >= 0)--res;tmp = res; *res++ = __la[-2];for (fir = __la - 2; fir-- != __fir; *res++ = *fir)while (res != tmp && (fir[0] - res[-1]) * (res[-1] - res[-2]) >= 0)--res;return res - 1;
} /* Granham */int main()
{freopen("Beauty.in" , "r", stdin );freopen("Beauty.out", "w", stdout);scanf("%d", &n);for (int i = 0; i < n; ++i)scanf("%d%d", &p[i].x, &p[i].y);std::sort(p, p + n, cmp);n = Granham(p, p + n, res) - res;int ans = 0;for (const vec *ths = res, *oppo = res + 2; ths != res + n; ++ths)//注意这里oppo必须从res + 2开始枚举,否则错。{while ((oppo[1] - ths[0]) * (oppo[1] - ths[1])> (oppo[0] - ths[0]) * (oppo[0] - ths[1]))if (++oppo == res + n) oppo = res;gmax(ans, (*oppo - *ths).sqrabs());} /* for */printf("%d\n", ans); return 0;
} /* main *//*旋转卡壳模板题,不再多说。*/

半平面交

poj2451 Uyuw's Concert

/**********************************\* @prob: poj2451 Uyuw's Concert  ** @auth: Wang Junji              ** @stat: Accepted.               ** @date: June. 26th. 2012        ** @memo: 半平面交                 *
\**********************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <deque>using std::deque;
typedef double DBL;
const int maxN = 20010;
const DBL zero = 1e-12L;struct vec
{DBL x, y; vec() {} /* vec */ vec(DBL x, DBL y): x(x), y(y) {} /* vec */vec operator-(const vec& b) const {return vec(x - b.x, y - b.y);} /* operator- */vec operator+(const vec& b) const {return vec(x + b.x, y + b.y);} /* operator+ */vec operator*(const DBL& t) const {return vec(x * t, y * t);} /* operator* */DBL operator*(const vec& b) const {return x * b.y - y * b.x;} /* operator* */
} p[maxN];struct HP
{vec A, B; DBL ang; HP() {} /* HP */HP(const vec& A, const vec& B): A(A), B(B){ang = atan2(B.y - A.y, B.x - A.x);}/* HP */
} hp[maxN]; int n;inline int sgn(const DBL& x) {return x < -zero ? -1 : x > zero ? 1 : 0;} /* sgn */
inline DBL sqr(const DBL& x) {return x * x;} /* sqr */
inline bool eql(const HP& a, const HP& b) {return !sgn(a.ang - b.ang);} /* eql */
inline bool notin(const vec& P, const HP& a) {return (P - a.B) * (P - a.A) > -zero;} /* notin */inline int cmp(const void* __a, const void* __b)
{const HP &a = *(HP*)__a, &b = *(HP*)__b;int tmp = sgn(a.ang - b.ang);if (tmp) return tmp;return sgn((b.B - a.A) * (b.A - a.A));
} /* cmp */inline vec cross(const HP& a, const HP& b)
{vec AB = a.B - a.A, CD = b.B - b.A,AC = b.A - a.A, AD = b.B - a.A;return a.A + AB * ((AC * AD) / (AB * CD));
} /* cross */inline const deque <HP>&
Half_Plane_Inter(const HP* fir, const HP* la)
{static deque <HP> q; q.clear();for (q.push_back(*fir++), q.push_back(*fir++); fir != la; q.push_back(*fir++)){while (q.size() > 1 && notin(cross(*(q.end() - 2), q.back()), *fir)) q.pop_back();while (q.size() > 1 && notin(cross(q.front(), *(q.begin() + 1)), *fir)) q.pop_front();} /* for */for (;;){bool flag = 0;while (q.size() > 2 && notin(cross(*(q.end() - 2), q.back()), q.front()))q.pop_back(), flag = 1;while (q.size() > 2 && notin(cross(q.front(), *(q.begin() + 1)), q.back()))q.pop_front(), flag = 1;if (!flag) break;} /* for */return q;
} /* Half_Plane_Inter */int main()
{freopen("Concert.in" , "r", stdin );freopen("Concert.out", "w", stdout);scanf("%d", &n);for (int i = 0; i < n; ++i){DBL x1, y1, x2, y2;scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);hp[i] = HP(vec(x1, y1), vec(x2, y2));} /* for */hp[n++] = HP(vec(0  , 0  ), vec(1e4, 0  ));hp[n++] = HP(vec(1e4, 0  ), vec(1e4, 1e4));hp[n++] = HP(vec(1e4, 1e4), vec(0  , 1e4));hp[n++] = HP(vec(0  , 1e4), vec(0  , 0  ));qsort(hp, n, sizeof hp[0], cmp);n = std::unique(hp, hp + n, eql) - hp;deque <HP> res = Half_Plane_Inter(hp, hp + n);if (res.size() < 3) printf("0.0\n");else{n = 0;p[n++] = cross(res.front(), res.back());for (deque <HP>::const_iterator iter = res.begin(); iter + 1 != res.end(); ++iter)p[n++] = cross(*iter, *(iter + 1));DBL ans = 0;for (int i = 1; i + 1 < n; ++i)ans += fabs((p[i + 1] - p[0]) * (p[i] - p[0]));printf("%.1lf\n", ans /= 2);} /* else */return 0;
} /* main *//*半平面交的模板题。
注意不能使用long double类型,否则超时。*/

poj3384 Feng Shui

/*****************************\* @prob: poj3384 Feng Shui  ** @auth: Wang Junji         ** @stat: Accepted.          ** @date: June. 28th, 2012   ** @memo: 半平面交            *
\*****************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <deque>
#include <cmath>using std::deque;
const int maxN = 210;
const double zero = 1e-10;struct vec
{double x, y; vec() {} /* vec */ vec(double x, double y): x(x), y(y) {} /* vec */vec operator-(const vec& b) const {return vec(x - b.x, y - b.y);} /* operator- */vec operator+(const vec& b) const {return vec(x + b.x, y + b.y);} /* operator+ */vec operator*(const double& t) const {return vec(x * t, y * t);} /* operator* */double operator*(const vec& b) const {return x * b.y - y * b.x;} /* operator* */double abs() const {return sqrt(x * x + y * y);} /* abs */
} p[maxN];struct HP
{vec A, B; double ang; HP() {} /* HP */HP(const vec& A, const vec& B): A(A), B(B) {ang = atan2(B.y - A.y, B.x - A.x);} /* HP */void mv(const double& r){double d = (B - A).abs(), x1 = A.x, x2 = B.x, y1 = A.y, y2 = B.y;A.x += (y1 - y2) * r / d;B.x += (y1 - y2) * r / d;A.y += (x2 - x1) * r / d;B.y += (x2 - x1) * r / d;} /* mv */
} hp[maxN]; double Rad; int n;inline int sgn(const double& x) {return x < -zero ? -1 : x > zero ? 1 : 0;} /* sgn */inline int cmp(const void* __a, const void* __b)
{const HP &a = *(HP*)__a, &b = *(HP*)__b;int tmp = sgn(a.ang - b.ang);if (tmp) return tmp;return sgn((b.B - a.A) * (b.A - a.A));
} /* cmp */inline bool eql(const HP& a, const HP& b) {return !sgn(a.ang - b.ang);} /* eql */inline vec cross(const HP& a, const HP& b)
{vec AB = a.B - a.A, CD = b.B - b.A,AC = b.A - a.A, AD = b.B - a.A;return a.A + AB * ((AC * AD) / (AB * CD));
} /* cross */inline bool outof(const vec& P, const HP& a)
{return (P - a.B) * (P - a.A) > zero;}
/* outof */
//这里不能排除三点共线的情况。inline const deque <HP>&
Half_Plane_Inter(const HP* fir, const HP* la)
{static deque <HP> q; q.clear();for (q.push_back(*fir++), q.push_back(*fir++); fir != la; q.push_back(*fir++)){while (q.size() > 1 && outof(cross(*(q.end() - 2), q.back())   , *fir)) q.pop_back ();while (q.size() > 1 && outof(cross(q.front(), *(q.begin() + 1)), *fir)) q.pop_front();} /* for */for (;;){bool flag = 0;while (q.size() > 2 && outof(cross(*(q.end() - 2), q.back())   , q.front()))q.pop_back (), flag = 1;while (q.size() > 2 && outof(cross(q.front(), *(q.begin() + 1)), q.back ()))q.pop_front(), flag = 1;if (!flag) break;} /* for */return q;
} /* Half_Plane_Inter */int main()
{freopen("Feng_Shui.in" , "r", stdin );freopen("Feng_Shui.out", "w", stdout);while (~scanf("%d%lf", &n, &Rad)){for (int i = 0; i < n; ++i)scanf("%lf%lf", &p[i].x, &p[i].y);p[n] = p[0];for (int i = 0; i < n; ++i)hp[i] = HP(p[i + 1], p[i]), hp[i].mv(Rad);qsort(hp, n, sizeof hp[0], cmp);n = std::unique(hp, hp + n, eql) - hp;const deque <HP> res = Half_Plane_Inter(hp, hp + n);if (res.size() < 3){vec tmp = cross(hp[0], hp[1]);printf("%.4lf %.4lf %.4lf %.4lf\n", tmp.x, tmp.y, tmp.x, tmp.y);} /* if */else{n = 0;for (deque <HP>::const_iterator iter = res.begin(); iter + 1 != res.end(); ++iter)p[n++] = cross(*iter, *(iter + 1));p[n++] = cross(res.back(), res.front());p[n] = p[0];vec p1, p2;double ans = 0;for (int i = 0; i + 1 < n; ++i)for (int j = i + 1; j < n; ++j){double d = (p[i] - p[j]).abs();if (d - ans > -zero) ans = d, p1 = p[i], p2 = p[j];} /* for */if (p1.x > p2.x) std::swap(p1, p2);printf("%.4lf %.4lf %.4lf %.4lf\n", p1.x, p1.y, p2.x, p2.y);} /* else */} /* while */return 0;
} /* main *//*这道题的Special Judge有点问题,需要注意:1) 半平面交时不能排除三点共线的情况(这并不是Sepical Judge的问题,因为这样会排除可能的最优解);2) 求最远点对时只能用枚举的方法,不能旋转卡壳;3) 输出最后结果时,保证第一个点的横坐标小于第二个点;4) 枚举最远点对时,若当前值大于等于最大值时更新,而不是大于。还要注意半平面交为空的情况,这时候应当通过原始边来找到中间的唯一解。*/

poj1279 Art Gallery

/*******************************\* @prob: poj1279 Art Gallery  ** @auth: Wang Junji           ** @stat: Accepted.            ** @date: June. 28th, 2012     ** @memo: 半平面交              *
\*******************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <deque>using std::deque;
const int maxN = 1510;
const double zero = 1e-8;struct vec
{double x, y; vec() {} /* vec */ vec(double x, double y): x(x), y(y) {} /* vec */vec operator-(const vec& b) const {return vec(x - b.x, y - b.y);} /* operator- */vec operator+(const vec& b) const {return vec(x + b.x, y + b.y);} /* operator+ */vec operator*(const double& t) const {return vec(x * t, y * t);} /* operator* */double operator*(const vec& b) const {return x * b.y - y * b.x;} /* operator* */
} p[maxN];struct HP
{vec A, B; double ang; HP() {} /* HP */HP(const vec& A, const vec& B): A(A), B(B){ang = atan2(B.y - A.y, B.x - A.x);} /* HP */
} hp[maxN];
int n, T;inline int sgn(const double& x)
{return x < -zero ? -1 : x > zero ? 1 : 0;}
/* sgn */inline bool eql(const HP& a, const HP& b) {return !sgn(a.ang - b.ang);} /* eql */inline int cmp(const void* __a, const void* __b)
{const HP &a = *(HP*)__a, &b = *(HP*)__b;int tmp = sgn(a.ang - b.ang);if (tmp) return tmp;return sgn((b.B - a.A) * (b.A - a.A));
} /* cmp */inline vec cross(const HP& a, const HP& b)
{vec AB = a.B - a.A, CD = b.B - b.A,AC = b.A - a.A, AD = b.B - a.A;return a.A + AB * ((AC * AD) / (AB * CD));
} /* cross */inline bool notin(const vec& P, const HP& a)
{return (P - a.B) * (P - a.A) > -zero;}
/* notin */inline const deque <HP>&
Half_Plane_Inter(const HP* fir, const HP* la)
{static deque <HP> q; q.clear();for (q.push_back(*fir++), q.push_back(*fir++); fir != la; q.push_back(*fir++)){while (q.size() > 1 && notin(cross(*(q.end() - 2), q.back())   , *fir)) q.pop_back ();while (q.size() > 1 && notin(cross(q.front(), *(q.begin() + 1)), *fir)) q.pop_front();} /* for */for (;;){bool flag = 0;while (q.size() > 2 && notin(cross(*(q.end() - 2), q.back())   , q.front()))q.pop_back (), flag = 1;while (q.size() > 2 && notin(cross(q.front(), *(q.begin() + 1)), q.back ()))q.pop_front(), flag = 1;if (!flag) break;} /* for */return q;
} /* Half_Plane_Inter */int main()
{freopen("gallery.in" , "r", stdin );freopen("gallery.out", "w", stdout);for (scanf("%d", &T); T--;){scanf("%d", &n);for (int i = 0; i < n; ++i) scanf("%lf%lf", &p[i].x, &p[i].y);p[n] = p[0];for (int i = 0; i < n; ++i) hp[i] = HP(p[i + 1], p[i]);qsort(hp, n, sizeof hp[0], cmp);n = std::unique(hp, hp + n, eql) - hp;const deque <HP> res = Half_Plane_Inter(hp, hp + n);if (res.size() < 3) printf("0.00\n");else{n = 0;double ans = 0;for (deque <HP>::const_iterator iter = res.begin(); iter + 1 != res.end(); ++iter)p[n++] = cross(*iter, *(iter + 1));p[n++] = cross(res.front(), res.back());for (const vec* ths = p + 1; ths + 1 != p + n; ++ths)ans += fabs((ths[0] - p[0]) * (ths[1] - p[0]));printf("%.2lf\n", ans /= 2);} /* else */} /* for */return 0;
} /* main *//*半平面交模板题,不多说。*/

poj3525 Most Distant Point from the Sea

/*********************************************************\* @prob: poj3525 Most Distant Point from the Sea        ** @auth: Wang Junji        * @stat: Accepted.           ** @date: June. 26th. 2012  * @memo: 半平面交、二分枚举     *
\*********************************************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <deque>
#include <cmath>using std::deque;
const int maxN = 110;
const double zero = 1e-10;struct vec
{double x, y; vec() {} /* vec */ vec(double x, double y): x(x), y(y) {} /* vec */vec operator-(const vec& b) const {return vec(x - b.x, y - b.y);} /* operator- */vec operator+(const vec& b) const {return vec(x + b.x, y + b.y);} /* operator+ */vec operator*(const double& t) const {return vec(x * t, y * t);} /* operator* */double operator*(const vec& b) const {return x * b.y - y * b.x;} /* operator* */double abs() const {return sqrt(x * x + y * y);} /* abs */
} p[maxN];struct HP
{vec A, B; double ang, len; HP() {} /* HP */HP(const vec& A, const vec& B): A(A), B(B){ang = atan2(B.y - A.y, B.x - A.x);len = (B - A).abs();} /* HP */
} hp[maxN], hp1[maxN];
int n;inline int sgn(const double& x)
{return x < -zero ? -1 : x > zero ? 1 : 0;}
/* sgn */inline double sqr(const double& x) {return x * x;} /* sqr */inline int cmp(const void* __a, const void* __b)
{const HP &a = *(HP*)__a, &b = *(HP*)__b;int tmp = sgn(a.ang - b.ang);if (tmp) return tmp;return sgn((b.B - a.A) * (b.A - a.A));
} /* cmp */inline bool eql(const HP& a, const HP& b)
{return !sgn(a.ang - b.ang);}
/* eql */inline vec cross(const HP& a, const HP& b)
{vec AB = a.B - a.A, CD = b.B - b.A,AC = b.A - a.A, AD = b.B - a.A;return a.A + AB * ((AC * AD) / (AB * CD));
} /* cross */inline bool notin(const vec& P, const HP& a)
{return (P - a.B) * (P - a.A) > -zero;}
/* notin */inline bool Half_Plane_Inter(const HP* fir, const HP* la)
{static deque <HP> q; q.clear();for (q.push_back(*fir++), q.push_back(*fir++); fir != la; q.push_back(*fir++)){while (q.size() > 1 && notin(cross(*(q.end() - 2), q.back())   , *fir)) q.pop_back ();while (q.size() > 1 && notin(cross(q.front(), *(q.begin() + 1)), *fir)) q.pop_front();} /* for */for (;;){bool flag = 0;while (q.size() > 2 && notin(cross(*(q.end() - 2), q.back())   , q.front()))q.pop_back (), flag = 1;while (q.size() > 2 && notin(cross(q.front(), *(q.begin() + 1)), q.back ()))q.pop_front(), flag = 1;if (!flag) break;} /* for */return q.size() > 2;
} /* Half_Plane_Inter */inline bool check(double d)
{for (int i = 0; i < n; ++i){double x1 = hp[i].A.x, x2 = hp[i].B.x,y1 = hp[i].A.y, y2 = hp[i].B.y,len = hp[i].len;hp1[i].A.x = x1 + (y1 - y2) * d / len;hp1[i].B.x = x2 + (y1 - y2) * d / len;hp1[i].A.y = y1 + (x2 - x1) * d / len;hp1[i].B.y = y2 + (x2 - x1) * d / len;} /* for */return Half_Plane_Inter(hp1, hp1 + n);
} /* check */int main()
{freopen("sea.in" , "r", stdin );freopen("sea.out", "w", stdout);while (~scanf("%d", &n) && n){for (int i = 0; i < n; ++i)scanf("%lf%lf", &p[i].x, &p[i].y);p[n] = p[0];for (int i = 0; i < n; ++i)hp[i] = HP(p[i], p[i + 1]);std::qsort(hp, n, sizeof hp[0], cmp);n = std::unique(hp, hp + n, eql) - hp;double L = 0, R = 1e4;while (L - R < -zero){double Mid = (L + R) / 2;if (check(Mid)) L = Mid;else R = Mid;} /* while */printf("%.10lf\n", R);} /* while */return 0;
} /* main *//*相当于是求多边形内切圆半径。
只需要二分枚举,然后将所有的边向内移动半径的距离,求对应的半平面是否有相交的区域。*/

zoj2820 How I Mathematician Wonder What You Are!

/************************************************************\* @prob: zoj2820 How I Mathematician Wonder What You Are!  ** @auth: Wang Junji        * @stat: Accepted.              ** @date: June. 26th. 2012  * @memo: 半平面交、多边形内核      *
\************************************************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <deque>
#include <cmath>using std::deque;
const int maxN = 50;
const double zero = 1e-8;struct vec
{double x, y; vec() {} /* vec */ vec(const vec& b): x(b.x), y(b.y) {} /* vec */vec(double x, double y): x(x), y(y) {} /* vec */vec& operator=(const vec& b) {x = b.x, y = b.y; return *this;} /* operator= */vec operator-(const vec& b) const {return vec(x - b.x, y - b.y);} /* operator- */vec operator+(const vec& b) const {return vec(x + b.x, y + b.y);} /* operator+ */vec operator*(const double& d) const {return vec(x * d, y * d);} /* operator+ */double operator*(const vec& b) const {return x * b.y - y * b.x;} /* operator* */
} p[maxN];struct HP
{vec A, B; HP() {} /* HP */ HP(const HP& b): A(b.A), B(b.B) {} /* HP */HP(const vec& A, const vec& B): A(A), B(B) {} /* HP */HP& operator=(const HP& b) {A = b.A, B = b.B; return *this;} /* HP */operator vec() const {return B - A;} /* operator vec */double operator*(const HP& b) const {return (B - A) * (b.B - b.A);} /* operator* */double angle() const {return atan2(B.y - A.y, B.x - A.x);} /* angle */
} ele[maxN];
int n;vec cross(const HP& a, const HP& b)
{vec AB = vec(a), CD = vec(b),AC = b.A - a.A, AD = b.B - a.A;return a.A + AB * ((AC * AD) / (AB * CD));
} /* cross */inline int sgn(const double& x)
{return x < -zero ? -1 : x > zero ? 1 : 0;}
/* sgn */inline int cmp(const void* __a, const void* __b)
{const HP &a = *(HP*)__a, &b = *(HP*)__b;int tmp = sgn(a.angle() - b.angle());if (tmp) return tmp;return sgn((b.B - a.A) * (b.A - a.A));
} /* cmp */inline bool eql(const HP& a, const HP& b)
{return !sgn(a.angle() - b.angle());}
/* eql */inline bool notin(const vec& P, const HP& a)
{return (P - a.B) * (P - a.A) > -zero;}
/* notin */bool Core(HP const* fir, HP const* la)
{static deque <HP> q; q.clear();for (q.push_back(*fir++), q.push_back(*fir++); fir != la; q.push_back(*fir++)){while (q.size() > 1 && notin(cross(*(q.end() - 2), q.back()), *fir)) q.pop_back();while (q.size() > 1 && notin(cross(q.front(), *(q.begin() + 1)), *fir)) q.pop_front();} /* for */for (;;){bool flag = 0;while (q.size() > 2 && notin(cross(*(q.end() - 2), q.back()), q.front()))q.pop_back(), flag = 1;while (q.size() > 2 && notin(cross(q.front(), *(q.begin() + 1)), q.back()))q.pop_front(), flag = 1;if (!flag) break;} /* for */return q.size() > 2;
} /* Core */int main()
{freopen("Core.in" , "r", stdin );freopen("Core.out", "w", stdout);while (~scanf("%d", &n) && n){for (int i = 0; i < n; ++i)scanf("%lf%lf", &p[i].x, &p[i].y);p[n] = p[0];for (int i = 0; i < n; ++i)ele[i] = HP(p[i], p[i + 1]);qsort(ele, n, sizeof ele[0], cmp);n = std::unique(ele, ele + n, eql) - ele;printf("%d\n", Core(ele, ele + n));} /* while */return 0;
} /* main *//*半平面交模板题。
参考 http://evalls.yo2.cn/articles/%E5%8D%8A%E5%B9%B3%E9%9D%A2%E4%BA%A4onlogn%E7%9A%84%E7%AE%97%E6%B3%95.html1) 将所有半平面按极角排序,对于极角相同的,选择性的保留一个。2) 使用一个双端队列(deque),加入最开始2个半平面。3) 每次考虑一个新的半平面:a. while deque顶端的两个半平面的交点在当前半平面外:删除deque顶端的半平面b. while deque底部的两个半平面的交点在当前半平面外:删除deque底部的半平面c. 将新半平面加入deque顶端4) 删除两端多余的半平面。具体方法是:a. while deque顶端的两个半平面的交点在底部半平面外:删除deque顶端的半平面b. while deque底部的两个半平面的交点在顶端半平面外:删除deque底部的半平面重复a, b直到不能删除为止。5) 计算出deque顶端和底部的交点即可。*/

【计算几何】计算几何复习相关推荐

  1. 二维几何基础大合集!《计算几何全家桶(一)》(基础运算、点、线、多边形、圆、网格)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的模板整合计划 目录 1.基本运算 1.1 判断正负函数(sgn) 1.2 点积(数量积.内积)(Dot) 1.3 向量积 ...

  2. 计算几何、凸集、凸函数、凸规划简介

    计算几何.凸集.凸函数.凸规划简介目录 计算几何 计算几何理论中过两点的一条直线的表达式: 什么是仿射集 什么是凸集 三维空间的一个平面 超平面 凸函数 定义 Hessen矩阵的定义 判别方法 实例: ...

  3. 字符串算法 金策_GitHub - 662d7/shareOI: OI ACM 课件分享

    OI & ACM 课件分享 收集来自互联网上公开分享的信息竞赛学习课件 欢迎大家贡献,命名格式,题目_作者,接收 ppt 或 pdf 格式 如有侵权,麻烦提 Issues 或联系 hzwer@ ...

  4. 字符串算法 金策_GitHub - xjrjyy/shareOI: 算法竞赛课件分享

    算法竞赛课件分享 收集来自互联网上的算法竞赛学习课件 欢迎大家贡献,命名格式,题目_作者,接收 ppt 和 pdf 格式 如有侵权,麻烦提 Issues 或联系 hzwer@pku.edu.cn 删改 ...

  5. 字符串算法 金策_GitHub - hzwer/shareOI: 算法竞赛课件分享

    算法竞赛课件分享 收集来自互联网上的算法竞赛学习课件 欢迎大家贡献,命名格式,题目_作者,接收 ppt 和 pdf 格式 如有侵权,麻烦提 Issues 或联系 hzwer@pku.edu.cn 删改 ...

  6. 字符串算法 金策_OI ACM 课件收集整理

    最近收集整理了一些 OI 和 ACM 圈的公开课件和我自己讲课的课件,https://github.com/hzwer/shareOI,目前有上百个课件,涵盖了大部分算法,持续更新中,欢迎传阅,欢迎贡 ...

  7. maomao的每日动向

    \(2019.02.04\) \(Nothing\) \(to\) \(do\). \(2019.02.05\) - 早上睡到\(12\)点 - 中午下午:吃饭串门拜年 - 晚上:吹爆<流浪地球 ...

  8. ACM小白入门之必须要了解的东西

    ACM 国际大学生程序设计竞赛历史与介绍 程序设计竞赛是指考察程序设计能力的竞赛,分为解题竞赛.创意竞赛.性能竞赛等.程序设计竞赛的主要代表是 ACM-ICPC(ACM 国际大学生程序设计竞赛),AC ...

  9. MangataのACM模板

    文章目录 数据结构 并查集 树状数组 二维单点修改,区间查询 二维区间修改,单点查询 二维区间修改,区间查询 线段树 单点修改,区间查询 区间更新.区间查询 主席树(区间第k小数模板) 单调栈 单调队 ...

最新文章

  1. centos修改mysql密码_WAMP下修改MYSQL数据库密码
  2. Mysql之一:mysqldump和LVM逻辑卷快照
  3. 长尾关键词seo_为什么您不应该忘记长尾SEO
  4. 使用devops的团队_DevOps与兼职社区团队兼容吗?
  5. RecycleView嵌套滑动机制
  6. 挑战练习题2.3动态规划 poj3046 Ant Counting dp
  7. 微信小程序开发手机商城部分代码(不包括支付功能)
  8. i3 2310M i7 9700T i7 9700K MacBookPro 16寸 CPU 跑分对比
  9. 北京化工大学研究生学堂在线矩阵论及其应用答案
  10. linux at24测试程序,C51读写AT24C04源代码及AT24C04测试程序
  11. 手机通过WiFi控制电脑
  12. 机器人也能打排球了,击球成功率80%!日本东京大学新型气动仿人机器人
  13. J2EE是什么(一)
  14. 常见杀软对应的进程名
  15. 致翔OA漏洞复现手册
  16. 邮件html签名手机电脑不一致,HTML电子邮件签名不能在iPhone上正确渲染
  17. Ajax请求成功却执行error回调方法(Ajax跨域请求问题)
  18. jenkins构建Protractor项目报错解决
  19. css中a标签中去掉下划线注意事项
  20. MATLAB读取txt,excel,ASCII文件

热门文章

  1. outlook怎样同步服务器的文件夹,当您使用辅助在 Outlook 邮箱中的文件夹时的性能和同步问题...
  2. 2013年9—12月新托福考试终极报名指南!
  3. 不能作为c语言常量的是115L,c语言考试选择题
  4. python生成6位验证码随机数,需包含英文字母大写、小写和数字(含代码和注释)
  5. inline-bock间隙问题
  6. 关于空字符(NUL)在三种不同语言中的匹配
  7. multisim秒信号发生器_基于Multisim的简易信号发生器的设计
  8. 虚拟机VMware Workstation安装使用教程
  9. 无线通信中的小尺度衰落
  10. 计算机主机电源故障分析检测维修,电源故障:台式机电脑电源故障检修