zoukankan      html  css  js  c++  java
  • Codeforces Round #513 by Barcelona Bootcamp

    A. Phone Numbers

    签.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 110
     5 char s[N];
     6 int cnt[11], n;
     7 
     8 int main()
     9 {
    10     while (scanf("%d", &n) != EOF)
    11     {
    12         scanf("%s", s + 1);
    13         memset(cnt, 0, sizeof cnt);
    14         for (int i = 1; i <= n; ++i) 
    15             ++cnt[s[i] - '0']; 
    16         int res = 0;
    17         for (int i = 1;  i <= cnt[8]; ++i)
    18             res = max(res, min(i, (n - i) / 10));
    19         printf("%d
    ", res);
    20     }
    21     return 0;
    22 }
    View Code

    B. Maximum Sum of Digits

    Solved.

    题意:

    将一个数拆成$a + b = n$

    $要求S(a) + S(b)最大$

    $定义S(x) 为x的各位数字之和(以十进制表示)$

    思路:

    贪心构造一个数字$a有尽量多的9并且小于n即可$

    $为什么这样是对的$

    我们假设最优解为$a, b$

    $令a_i, b_i表示a, b的第i位$

    $如果存在某个a_i,不是9, 那么我们将它改成9$

    $那么对b_i的影响就是要减去差值$

    $如果造成退位,那么答案更优$

    $如果没有退位,那么答案不变$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 ll n;
     6 
     7 int f(ll x)
     8 {
     9     int res = 0;
    10     while (x)
    11     {
    12         res += x % 10;
    13         x /= 10;
    14     }
    15     return res;
    16 }
    17 
    18 int main()
    19 {
    20     while (scanf("%lld", &n) != EOF)
    21     {
    22         int res = 0;
    23         if (n <= 1000000) 
    24         {
    25             for (int i = 0; i <= n; ++i) 
    26                 res = max(res, f(i) + f(n - i));        
    27         }
    28         else
    29         {
    30             ll tmp = n;
    31             string s = "";
    32             while (tmp)
    33             {
    34                 if (tmp / 10) s += '9';
    35                 else if (tmp > 1) s += tmp - 1 + '0';
    36                 tmp /= 10;
    37             }
    38             ll x = 0;
    39             reverse(s.begin(), s.end());
    40             for (int i = 0, len = s.size(); i < len; ++i) x = x * 10 + s[i] - '0';
    41             res = f(x) + f(n - x);
    42             ll mid = n / 2; 
    43             for (ll i = max(0ll, mid - 1000000); i <= min(n, mid + 1000000); ++i)
    44                 res = max(res, f(i) + f(n - i));
    45         }
    46         printf("%d
    ", res);
    47     }    
    48     return 0;
    49 }
    View Code

    C. Maximum Subrectangle

    Solved.

    题意:

    有一个矩阵$c_{i, j} = a_i cdot b_j$

    $求一个最大子矩阵使得sumlimits_{i = x_1}^{x_2} sumlimits_{i = y_1}^{y_2} c_{i, j} <= x$

    思路:

    我们考虑将求和的式子变换一下

    $sumlimits_{i = x_1}^{x_2} sumlimits_{i = y_1}^{y_2} c_{i, j} = $

    $sumlimits_{i = x_1}^{x_2} sumlimits_{i = y_1}^{y_2} a_i cdot b_j = $

    $sumlimits_{i = x_1}^{x_2} a_i cdot sumlimits_{i = y_1}^{y_2} b_j $

    那么我们要想使面积最大

    只要先预处理出长度为$x的子段和最小的a[] 和 长度为y的字段和最小的b[]$

    $再枚举x, y更新答案即可$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 2010
     6 int n, m, a[N], b[N];
     7 ll x;
     8 int f[N], g[N];
     9 
    10 int main()
    11 {
    12     while (scanf("%d%d", &n, &m) != EOF)
    13     {
    14         for (int i = 1; i <= n; ++i) scanf("%d", a + i), a[i] += a[i - 1];
    15         for (int i = 1; i <= m; ++i) scanf("%d", b + i), b[i] += b[i - 1];
    16         scanf("%lld", &x);
    17         memset(f, 0x3f, sizeof f);
    18         memset(g, 0x3f, sizeof g);
    19         for (int i = 1; i <= n; ++i)
    20             for (int j = i; j <= n; ++j)
    21                 f[j - i + 1] = min(f[j - i + 1], a[j] - a[i - 1]);
    22         for (int i = 1; i <= m; ++i)
    23             for (int j = i; j <= m; ++j)
    24                 g[j - i + 1] = min(g[j - i + 1], b[j] - b[i - 1]);
    25         int res = 0;
    26         for (int i = 1; i <= n; ++i)
    27             for (int j = 1; j <= m; ++j)
    28                 if (1ll * f[i] * g[j] <= x)
    29                     res = max(res, i * j);
    30         printf("%d
    ", res);
    31     }
    32     return 0;
    33 }
    View Code

    D. Social Circles

    Solved.

    题意:

    有$n个人,要坐在若干个圆桌上,每个人要求左边和右边至少有l_i 和r_i个空凳子$

    $空凳子部分可以交叉$

    至少需要几张凳子

    思路:

    我们考虑答案就是$sum l_i + sum r_i + n - 交叉部分$

    $那么我们就是尽量让交叉部分大即可$

    $那么右边空凳子需求多的要和左边空凳子需求多的相邻即可$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 100010
     6 int n;
     7 int l[N], r[N];
     8 
     9 int main()
    10 {
    11     while (scanf("%d", &n) != EOF)
    12     {
    13         for (int i = 1; i <= n; ++i) scanf("%d%d", l + i, r + i);
    14         sort(l + 1, l + 1 + n);
    15         sort(r + 1, r + 1 + n);
    16         ll res = 0;
    17         for (int i = 1; i <= n; ++i) res += max(l[i], r[i]);
    18         printf("%lld
    ", res + n);
    19     }
    20     return 0;
    21 }
    View Code

    E. Sergey and Subway

    Solved.

    题意:

    给出一棵树

    $现在如果有两个点共同邻接另外一个点$

    $那么就给这两个点连一条边$

    求新图中所有点对之间的最短距离

    思路:

    我们考虑新图中两点之间距离和原图之间的关系

    $我们考虑下面这样的$

    $1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8$

    $我们用dis[x] 表示x -> 1的距离$

    $在原图中$

    $dis_2 = 1, dis_3 = 2, dis_4 = 3, dis_5 = 4, dis_6 = 5, dis_7 = 6, dis_8 = 7$

    在新图中

    $dis_2 = 1, dis_3 = 1, dis_4 = 2, dis_5 = 2, dis_6 = 3, dis_7 = 3, dis_8 = 4$

    $我们发现新图和原图中距离的关系是$

    $dis_新 = (dis_原 + 1) / 2$

    $用线段树维护原图距离以及奇数个数再树形dp即可$

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define ll long long
      5 #define N 200010
      6 int n;
      7 vector <int> G[N];
      8 
      9 namespace SEG
     10 {
     11     struct node
     12     {
     13         ll a, b, lazy, cnt;
     14         void init()
     15         {
     16             a = b = lazy = cnt = 0;
     17         }
     18         void add(ll x)
     19         {
     20             a += x * cnt;
     21             lazy += x;
     22             if (abs(x) % 2)
     23                 b = cnt - b;
     24         }
     25         ll f()
     26         {
     27             return (a + b) / 2; 
     28         }
     29         node operator + (const node &other) const
     30         {
     31             node res; res.init();
     32             res.a = a + other.a;
     33             res.b = b + other.b;
     34             res.cnt = cnt + other.cnt;
     35             return res;
     36         }
     37     }a[N << 2];
     38     void build(int id, int l, int r)
     39     {
     40         a[id].init();
     41         a[id].cnt = r - l + 1;
     42         if (l == r) return;
     43         int mid = (l + r) >> 1;
     44         build(id << 1, l, mid);
     45         build(id << 1 | 1, mid + 1, r);
     46     }
     47     void pushdown(int id)
     48     {
     49         if (!a[id].lazy) return;
     50         a[id << 1].add(a[id].lazy);
     51         a[id << 1 | 1].add(a[id].lazy);
     52         a[id].lazy = 0;
     53     }
     54     void update(int id, int l, int r, int ql, int qr, int val)
     55     {
     56         if (l >= ql && r <= qr)
     57         {
     58             a[id].add(val);
     59             return;
     60         }
     61         int mid = (l + r) >> 1;
     62         pushdown(id);
     63         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
     64         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
     65         a[id] = a[id << 1] + a[id << 1 | 1];
     66     }
     67 }
     68 
     69 int fa[N], deep[N], in[N], out[N], cnt;
     70 void DFS(int u)
     71 {
     72     in[u] = ++cnt;
     73     for (auto v : G[u]) if (v != fa[u])
     74     {
     75         fa[v] = u;
     76         deep[v] = deep[u] + 1;
     77         DFS(v);
     78     }
     79     out[u] = cnt;
     80 }
     81 
     82 ll res;
     83 void DFS2(int u)
     84 {
     85     res += SEG::a[1].f();
     86     for (auto v : G[u]) if (v != fa[u])
     87     {
     88         SEG::update(1, 1, n, 1, n, 1);
     89         SEG::update(1, 1, n, in[v], out[v], -2);
     90         DFS2(v);
     91         SEG::update(1, 1, n, 1, n, -1);
     92         SEG::update(1, 1, n, in[v], out[v], 2);
     93     }
     94 }
     95 int main()
     96 {
     97     while (scanf("%d", &n) != EOF)
     98     {
     99         cnt = 0; res = 0;
    100         for (int i = 1; i <= n; ++i) G[i].clear();
    101         for (int i = 1, u, v; i < n; ++i)
    102         {
    103             scanf("%d%d", &u, &v);
    104             G[u].push_back(v);
    105             G[v].push_back(u);
    106         }
    107         deep[1] = 0;
    108         DFS(1);
    109         SEG::build(1, 1, n);
    110         for (int i = 1; i <= n; ++i) SEG::update(1, 1, n, in[i], in[i], deep[i]);
    111         DFS2(1);
    112         printf("%lld
    ", res / 2);
    113     }
    114     return 0;
    115 }
    View Code
  • 相关阅读:
    SCILAB简介[z]
    UG OPEN API编程基础 2约定及编程初步
    Office 2003与Office 2010不能共存的解决方案
    UG OPEN API 编程基础 3用户界面接口
    NewtonRaphson method
    UG OPEN API编程基础 13MenuScript应用
    UG OPEN API编程基础 14API、UIStyler及MenuScript联合开发
    UG OPEN API编程基础 4部件文件的相关操作
    UG OPEN API编程基础 1概述
    16 UG Open的MFC应用
  • 原文地址:https://www.cnblogs.com/Dup4/p/10363805.html
Copyright © 2011-2022 走看看