zoukankan      html  css  js  c++  java
  • 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[]) {;}
  • 相关阅读:
    (转载)delphi checklistbox用法
    (转载)c++builder/delphi中透明panel及透明窗口的实现方法_delphi教程
    (转载)图片的漫游
    (转载)SQL中导入图片
    (转载)使用ADOConnet.BeginTrans后,出现错误提示:无法在此会话中启动更多的事务?
    (转载)delphi 中如何调用sql 存储过程
    C# 读取注册表获取本机的全部的typelib信息
    EXCEL 引用autocad vba,自动加载其类型库
    AutoCAD2013 以上利用AccoreConsole+ c# NetApi Windows Froms 封装
    Aveva Marine 新建项目001
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7421331.html
Copyright © 2011-2022 走看看