• BZOJ 4445: [Scoi2015]小凸想跑步


    二次联通门 : BZOJ 4445: [Scoi2015]小凸想跑步

    /*
        BZOJ 4445: [Scoi2015]小凸想跑步
        
        计算几何
        对于给定的凸包(就是题目中给的多边形)
        考虑对于每一条边都会有一个临界线
        在直线上时左右的价值相等
    
        在直线的某一侧会更优(另一侧则会更差)
        那这样求出每条边的这条直线,再把01边添入
        做一个半平面交就好了
    代码参考的由乃dalao的代码
    */ #include <cstdio> #include <iostream> #include <cmath> #include <algorithm> const int BUF = 12312312; char Buf[BUF], *buf = Buf; #define flo double inline void read (int &now) { bool temp = false; for (now = 0; !isdigit (*buf); ++ buf) if (*buf == '-') temp = true; for (; isdigit (*buf); now = now * 10 + *buf - '0', ++ buf); if (temp) now = -now; } #define Max 100005 struct P { flo x, y; }; P p[Max], _q[Max]; struct L { P u, v; flo a; inline void Cal () { a = atan2 (v.y, v.x); } }; L q[Max], r[Max]; P operator + (P a, P b) { return (P) { a.x + b.x, a.y + b.y }; } P operator - (P a, P b) { return (P) { a.x - b.x, a.y - b.y }; } P operator * (flo a, P b) { return (P) { a * b.x, a * b.y }; } flo Cross (P a, P b) { return a.x * b.y - a.y * b.x; } flo Cal (P a, L b) { return Cross (a - b.u, b.v); } P Over (L a, L b) { return a.u + Cross (a.u - b.u, b.v) / Cross (b.v, a.v) * a.v; } bool operator < (L a, L b) { return a.a < b.a || a.a == b.a && Cal (a.u, b) < 0; } void Insert (int i, int j) { flo a = p[0].y - p[i].y - p[1].y + p[j].y; flo b = p[1].x - p[j].x - p[0].x + p[i].x; flo c = Cross (p[0], p[1]) - Cross (p[i], p[j]); r[i].u.x = b ? 0 : -c / a, r[i].u.y = b ? -c / b : 0; r[i].v = (P) {-b, a}; } flo Cal_area (P *p, int N) { flo res = Cross (p[N - 1], p[0]); for (register int i = 1; i < N; ++ i) res += Cross (p[i - 1], p[i]); return res; } int Main () { fread (buf, 1, BUF, stdin); int N; read (N); register int i; int x; for (i = 0; i < N; ++ i) read (x), p[i].x = x, read (x), p[i].y = x; r[0].u = p[0], r[0].v = p[1] - p[0]; for (i = 1; i < N; ++ i) Insert (i, (i + 1) % N); for (i = 0; i < N; ++ i) r[i].Cal (); std :: sort (r, r + N); int L = 0, R = -1; for (i = 0; i < N; ++ i) { for (; L < R && Cal (_q[R], r[i]) > 0; -- R); for (; L < R && Cal (_q[L + 1], r[i]) > 0; ++ L); if (L > R || r[i].a != q[R].a) q[++ R] = r[i], _q[R] = Over (q[R], q[R - 1]); } for (; L < R && Cal (_q[R], q[L]) > 0; -- R); _q[L] = Over (q[L], q[R]); flo Answer = Cal_area (_q + L, R - L + 1) / Cal_area (p, N); printf ("%.4lf", Answer); return 0; } int ZlycerQan = Main (); int main (int argc, char *argv[]) {;}
  • 相关阅读:
    编写可测试的程序
    系统程序员成长计划序
    编写可移植C/C++程序的要点
    Android IPC机制详解
    WordPress Attack Scanner插件多个信息泄露漏洞
    WordPress Simple History Plugin RSS Feed 信息泄露漏洞
    WordPress Poll插件多个SQL注入漏洞
    WordPress yolink Search插件‘s’参数跨站脚本漏洞
    WordPress Poll插件跨站请求伪造漏洞
    Python 'stringobject.c'多个远程缓冲区溢出漏洞
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7421331.html
Copyright © 2020-2023  润新知