zoukankan      html  css  js  c++  java
  • [SCOI2004]森林枚举 凸包

    15个可能是阶乘、2n次方、枚举、乘大系数、状压

    我犯的错误:

    清多组 

    1个点凸包特判 否则80

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 const int N = 1000;
     7 int n, x[N], y[N], w[N], l[N], W, top, c, t1 = 0x3f3f3f3f, cho, t3;
     8 double t2, r, L;
     9 bool v[N];
    10 struct Q {
    11     int x, y;
    12 }p[N], stk[N];
    13 inline bool cmp (const Q & a, const Q & b)
    14 {
    15     return a.y == b.y ? a.x < b.x : a.y < b.y;
    16 }
    17 inline int t (const Q & a, const Q & b, const Q & c)
    18 {
    19     int x1 = b.x - a.x, y1 = b.y - a.y;
    20     int x2 = c.x - b.x, y2 = c.y - b.y;
    21     return x1 * y2 - x2 * y1;
    22 }
    23 inline double d (const Q & a, const Q & b)
    24 {
    25     return sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    26 }
    27 inline double ck ()
    28 {
    29     c = 0;
    30     for (int i = 1; i <= n; i ++)
    31         if (!v[i])
    32             p[++ c].x = x[i], p[c].y = y[i];
    33     sort (p + 1, p + 1 + c, cmp);
    34     top = 0;
    35     stk[++ top] = p[1];
    36     stk[++ top] = p[2];
    37     for (int i = 3; i <= c; i ++)
    38     {
    39         while (top > 1 && t (stk[top - 1], stk[top], p[i]) < 0) top --;
    40         stk[++ top] = p[i];
    41     }
    42     int base = top;
    43     stk[++ top] = p[c - 1];
    44     for (int i = c - 2; i >= 1; i --)
    45     {
    46         while (top > base && t (stk[top - 1], stk[top], p[i]) < 0) top --;
    47         stk[++ top] = p[i];
    48     }
    49     double z (0);
    50     if (c == 1) top = 1;
    51     for (int i = 2; i <= top; i ++)
    52         z += d (stk[i], stk[i - 1]);
    53     return z;
    54 }
    55 inline int calc (int x)
    56 {
    57     int c (0);
    58     for (int i = 0; i < n; i ++)
    59         if (x >> i & 1)
    60             c ++;
    61     return c;
    62 }
    63 inline void M (int x)
    64 {
    65     memset (v, 0, sizeof v);
    66     W = 0, L = 0;
    67     for (int i = 0; i < n; i ++)
    68         if (x >> i & 1)
    69             v[i + 1] = true, W += w[i + 1], L += l[i + 1];
    70     r = ck ();
    71     if (r < L && W < t1)
    72         t1 = W, t2 = L - r, t3 = calc (x), cho = x;
    73     if (r < L && W == t1)
    74         if (calc (x) < t3)
    75             t1 = W, t2 = L - r, t3 = calc (x), cho = x;
    76 }
    77 int main ()
    78 {
    79     scanf ("%d", &n);
    80     for (int i = 1; i <= n; i ++)
    81         scanf ("%d%d%d%d", &x[i], &y[i], &w[i], &l[i]);
    82     for (int i = 0; i < (1 << n) - 1; i ++)
    83         M (i);
    84     printf ("%.2lf\n", t2);
    85     for (int i = 0; i < n; i ++)
    86         if ((cho >> i) & 1)
    87             printf ("%d ", i + 1);
    88     return 0;
    89 }
  • 相关阅读:
    python note 19 异常处理
    python note 18 序列化模块
    python note 17 random、time、sys、os模块
    python note 16 re模块的使用
    python note 15 正则表达式
    python note 13 内置函数
    python note 12 生成器、推导式
    C++ int型负数除法取余问题
    Leetcode162. 寻找峰值
    Leetcode450. 删除二叉搜索树中的节点
  • 原文地址:https://www.cnblogs.com/tellmewtf/p/2781840.html
Copyright © 2011-2022 走看看