zoukankan      html  css  js  c++  java
  • 51NOD

    给一个共有n个点的凸多边形,求一条将该多边形划分为面积和周长都相等的两部分的直线。
    Input
    第一行一个正整数n,表示多边形的点数。(n <= 40000)
    接下来的n行,第i+1行,每行两个实数xi,yi,表示凸多边形的一个点的坐标,点按照逆时针或顺时针的顺序给出。
    其中n,|xi|,|yi|<=40000。
    Output
    如果存在这样的直线,将这条直线与凸多边形的两个交点的坐标分两行输出。你所求的直线必须与多边形有两个交点,且分多边形的两部分周长或面积相差都不能大于10^-3。
    如果不存在,输出"impossible"(不含引号)。
    Input示例
    4
    0 0
    3 0
    3 3
    0 3
    Output示例
    1 0
    2 3

    解法:
    任选多边形上一点,设周长为C,面积为S, p[x]表示顺时针沿着边走x长度的点,f(x)表示p[x],p[x + C / 2]以及沿途经过的顶点构成的多边形的面积 - S / 2。
    则显然f(x) = -f(x + C / 2),由零点存在定理知[x, x + C / 2]中必有一解使函数值为0。二分找零点即可。
      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pii pair<int, int>
     27 #define pb push_back
     28 #define pli pair<ll, int>
     29 #define pil pair<int, ll>
     30 #define clr(a, x) memset(a, x, sizeof(a))
     31 
     32 const double pi = acos(-1.0);
     33 const int INF = 0x3f3f3f3f;
     34 const int MOD = 1e9 + 7;
     35 const double EPS = 1e-9;
     36 
     37 /*
     38 #include <ext/pb_ds/assoc_container.hpp>
     39 #include <ext/pb_ds/tree_policy.hpp>
     40 using namespace __gnu_pbds;
     41 #define TREE tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update>
     42 TREE T;
     43 */
     44 
     45 struct Point {
     46     double x, y;
     47     Point () {}
     48     Point (double x, double y) : x(x), y(y) {}
     49     Point operator - (const Point &p) const {
     50         return Point(x - p.x, y - p.y);
     51     }
     52     double operator ^ (const Point &p) const {
     53         return x * p.y - y * p.x;
     54     }
     55     double len() {
     56         return sqrt(x * x + y * y);
     57     }
     58     bool operator == (const Point &p) const {
     59         return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
     60     }
     61     void input() {
     62         scanf("%lf%lf", &x, &y);
     63     }
     64     void output() {
     65         printf("%.12f %.12f
    ", x, y);
     66     }
     67 } p[40015], p1[40015], p2[40015];
     68 Point slice(Point p1, Point p2, double l) {
     69     double L = (p2 - p1).len();
     70     if (L < EPS) return p1;
     71     return Point(p1.x + (p2.x - p1.x) * l / L, p1.y + (p2.y - p1.y) * l / L);
     72 }
     73 double L[40015];
     74 double S(Point p[], int n) {
     75     double res = 0;
     76     for (int i = 0; i < n; ++i) {
     77         res += p[i] ^ p[(i + 1) % n];
     78     }
     79     return fabs(res);
     80 }
     81 int n;
     82 double totS;
     83 double cal(double x) {
     84     double sx = x, ex = x + L[n - 1] * 0.5;
     85     Point tp[40015];
     86     int index = 0;
     87     int id1 = upper_bound(L, L + n, sx) - L;
     88     int id2 = upper_bound(L, L + n, ex) - L;
     89     if (id1) sx -= L[id1 - 1];
     90     tp[index++] = slice(p[id1], p[(id1 + 1) % n], sx);
     91     for (int i = id1 + 1; i <= id2; ++i) {
     92         tp[index++] = p[i];
     93     }
     94     if (id2) ex -= L[id2 - 1];
     95     tp[index++] = slice(p[id2], p[(id2 + 1) % n], ex);
     96     return S(tp, index) - totS * 0.5;
     97 }
     98 Point get(double x) {
     99     int id = upper_bound(L, L + n, x) - L;
    100     if (id) x -= L[id - 1];
    101     return slice(p[id], p[(id + 1) % n], x);
    102 }
    103 int main() {
    104     scanf("%d", &n);
    105     for (int i = 0; i < n; ++i) {
    106         p[i].input();
    107     }
    108     totS = 0;
    109     for (int i = 0; i < n; ++i) {
    110         L[i] = L[i - 1] + (p[(i + 1) % n] - p[i]).len();
    111     }
    112     double s = 0, e = L[n - 1] * 0.5, mi;
    113     int f = cal(s) > 0;
    114     for (int rep = 1; rep <= 70; ++rep) {
    115         mi = (s + e) * 0.5;
    116         double v = cal(mi);
    117         if (fabs(v) < EPS) break;
    118         if (f == (v > 0)) {
    119             s = mi;
    120         } else {
    121             e = mi;
    122         }
    123     }
    124     get(mi).output();
    125     get(mi + L[n - 1] * 0.5).output();
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    制造者为什么重要
    归因理论
    初创业谨记有三法宝:顶梁柱、现金牛、北极星
    华特迪士尼语录
    说好一个创业故事的5个步骤
    接口
    抽象类_模板方法设计模式
    抽象类与抽象方法
    非static和static初始化块
    单例设计模式
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/9814979.html
Copyright © 2011-2022 走看看