• codeforces #595 div3 题解


    A. Yet Another Dividing into Teams

    Description

    Solution

     1 #include <algorithm>
     2 #include <cctype>
     3 #include <cmath>
     4 #include <cstdio>
     5 #include <cstdlib>
     6 #include <cstring>
     7 #include <iostream>
     8 #include <map>
     9 #include <queue>
    10 #include <set>
    11 #include <stack>
    12 #if __cplusplus >= 201103L
    13 #include <unordered_map>
    14 #include <unordered_set>
    15 #endif
    16 #include <vector>
    17 #define lson rt << 1, l, mid
    18 #define rson rt << 1 | 1, mid + 1, r
    19 #define LONG_LONG_MAX 9223372036854775807LL
    20 #define ll LL
    21 using namespace std;
    22 typedef long long ll;
    23 typedef long double ld;
    24 typedef unsigned long long ull;
    25 typedef pair<int, int> P;
    26 int n, m, k;
    27 const int maxn = 1e5 + 10;
    28 template <class T>
    29 inline T read()
    30 {
    31     int f = 1;
    32     T ret = 0;
    33     char ch = getchar();
    34     while (!isdigit(ch))
    35     {
    36         if (ch == '-')
    37             f = -1;
    38         ch = getchar();
    39     }
    40     while (isdigit(ch))
    41     {
    42         ret = (ret << 1) + (ret << 3) + ch - '0';
    43         ch = getchar();
    44     }
    45     ret *= f;
    46     return ret;
    47 }
    48 template <class T>
    49 inline void write(T n)
    50 {
    51     if (n < 0)
    52     {
    53         putchar('-');
    54         n = -n;
    55     }
    56     if (n >= 10)
    57     {
    58         write(n / 10);
    59     }
    60     putchar(n % 10 + '0');
    61 }
    62 template <class T>
    63 inline void writeln(const T &n)
    64 {
    65     write(n);
    66     puts("");
    67 }
    68 int a[maxn];
    69 int main(int argc, char const *argv[])
    70 {
    71 #ifndef ONLINE_JUDGE
    72     freopen("in.txt", "r", stdin);
    73     freopen("out.txt", "w", stdout);
    74 #endif
    75     int t = read<int>();
    76     while (t--)
    77     {
    78         n = read<int>();
    79         for (int i = 0; i < n; i++)
    80             a[i] = read<int>();
    81         sort(a, a + n);
    82         int f = 0;
    83         for (int i = 1; i < n; i++)
    84             if (a[i] == a[i - 1] + 1)
    85                 ++f;
    86         if (f)
    87             puts("2");
    88         else
    89             puts("1");
    90     }
    91     return 0;
    92 }
    View Code

    B. Books Exchange

    Description

    给出一个置换群,求每个循环的阶

    Solution

    dfs瞎搜一手

      1 #include <algorithm>
      2 #include <cctype>
      3 #include <cmath>
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <iostream>
      8 #include <map>
      9 #include <queue>
     10 #include <set>
     11 #include <stack>
     12 #if __cplusplus >= 201103L
     13 #include <unordered_map>
     14 #include <unordered_set>
     15 #endif
     16 #include <vector>
     17 #define lson rt << 1, l, mid
     18 #define rson rt << 1 | 1, mid + 1, r
     19 #define LONG_LONG_MAX 9223372036854775807LL
     20 #define ll LL
     21 using namespace std;
     22 typedef long long ll;
     23 typedef long double ld;
     24 typedef unsigned long long ull;
     25 typedef pair<int, int> P;
     26 int n, m, k;
     27 const int maxn = 2e5 + 10;
     28 template <class T>
     29 inline T read()
     30 {
     31     int f = 1;
     32     T ret = 0;
     33     char ch = getchar();
     34     while (!isdigit(ch))
     35     {
     36         if (ch == '-')
     37             f = -1;
     38         ch = getchar();
     39     }
     40     while (isdigit(ch))
     41     {
     42         ret = (ret << 1) + (ret << 3) + ch - '0';
     43         ch = getchar();
     44     }
     45     ret *= f;
     46     return ret;
     47 }
     48 template <class T>
     49 inline void write(T n)
     50 {
     51     if (n < 0)
     52     {
     53         putchar('-');
     54         n = -n;
     55     }
     56     if (n >= 10)
     57     {
     58         write(n / 10);
     59     }
     60     putchar(n % 10 + '0');
     61 }
     62 template <class T>
     63 inline void writeln(const T &n)
     64 {
     65     write(n);
     66     puts("");
     67 }
     68 int a[maxn], vis[maxn], step;
     69 void dfs(int u, int f)
     70 {
     71     if (a[u] == f)
     72     {
     73         vis[u] = step;
     74         return;
     75     }
     76     step++;
     77     dfs(a[u], f);
     78     vis[u] = step;
     79 }
     80 int main(int argc, char const *argv[])
     81 {
     82 #ifndef ONLINE_JUDGE
     83     freopen("in.txt", "r", stdin);
     84     freopen("out.txt", "w", stdout);
     85 #endif
     86     int t = read<int>();
     87     while (t--)
     88     {
     89         n = read<int>();
     90         memset(vis, 0, sizeof(int) * (n + 1));
     91         for (int i = 1; i <= n; i++)
     92             a[i] = read<int>();
     93         for (int i = 1; i <= n; i++)
     94         {
     95             if (!vis[i])
     96             {
     97                 step = 1;
     98                 dfs(i, i);
     99             }
    100         }
    101         for (int i = 1; i <= n; i++)
    102             printf("%d ", vis[i]);
    103         puts("");
    104     }
    105     return 0;
    106 }
    View Code

    C. Good Numbers

    Description

    给一个数n,找出一个最小的m使得m>=n,且m是3的幂次之和,同一幂次最多出现依次

    Solution

    十进制分解为三进制,当某一位是2或3(上一位进位而来)时,当前位赋值0,下一位++,注意判断最后进位,以及最后更新位置之前赋0

    三进制转回十进制即为答案

      1 #include <algorithm>
      2 #include <cctype>
      3 #include <cmath>
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <iostream>
      8 #include <map>
      9 #include <queue>
     10 #include <set>
     11 #include <stack>
     12 #if __cplusplus >= 201103L
     13 #include <unordered_map>
     14 #include <unordered_set>
     15 #endif
     16 #include <vector>
     17 #define lson rt << 1, l, mid
     18 #define rson rt << 1 | 1, mid + 1, r
     19 #define LONG_LONG_MAX 9223372036854775807LL
     20 #define ll LL
     21 using namespace std;
     22 typedef long long ll;
     23 typedef long double ld;
     24 typedef unsigned long long ull;
     25 typedef pair<int, int> P;
     26 ull n, m, k;
     27 const int maxn = 1e5 + 10;
     28 template <class T>
     29 inline T read()
     30 {
     31     int f = 1;
     32     T ret = 0;
     33     char ch = getchar();
     34     while (!isdigit(ch))
     35     {
     36         if (ch == '-')
     37             f = -1;
     38         ch = getchar();
     39     }
     40     while (isdigit(ch))
     41     {
     42         ret = (ret << 1) + (ret << 3) + ch - '0';
     43         ch = getchar();
     44     }
     45     ret *= f;
     46     return ret;
     47 }
     48 template <class T>
     49 inline void write(T n)
     50 {
     51     if (n < 0)
     52     {
     53         putchar('-');
     54         n = -n;
     55     }
     56     if (n >= 10)
     57     {
     58         write(n / 10);
     59     }
     60     putchar(n % 10 + '0');
     61 }
     62 template <class T>
     63 inline void writeln(const T &n)
     64 {
     65     write(n);
     66     puts("");
     67 }
     68 ull p[50];
     69 void init()
     70 {
     71     p[0] = 1;
     72     for (int i = 1; i < 50; i++)
     73         p[i] = p[i - 1] * 3;
     74 }
     75 vector<int> t3;
     76 ull solve()
     77 {
     78     t3.clear();
     79     while (n)
     80     {
     81         t3.emplace_back(n % 3);
     82         n /= 3;
     83     }
     84     int sz = t3.size();
     85     int f = -1;
     86     for (int i = 0; i < sz; i++)
     87         if (t3[i] == 2 || t3[i] == 3)
     88         {
     89             f = i;
     90             if (i != sz - 1)
     91             {
     92                 t3[i] = 0;
     93                 t3[i + 1]++;
     94             }
     95             else
     96             {
     97                 t3[i] = 0;
     98                 t3.emplace_back(1);
     99             }
    100         }
    101     sz = t3.size();
    102     ull res = 0;
    103     if (f != -1)
    104         for (int i = 0; i < f; i++)
    105             t3[i] = 0;
    106     for (int i = 0; i < sz; i++)
    107         if (t3[i])
    108             res += p[i];
    109     return res;
    110 }
    111 int main(int argc, char const *argv[])
    112 {
    113 #ifndef ONLINE_JUDGE
    114     freopen("in.txt", "r", stdin);
    115     // freopen("out.txt", "w", stdout);
    116 #endif
    117     init();
    118     int t = read<int>();
    119     while (t--)
    120     {
    121         n = read<ull>();
    122         writeln(solve());
    123     }
    124     return 0;
    125 }
    View Code

    D1. Too Many Segments

    Description

    给n个区间,一个上界k
    问最少删除多少区间,使得区间内任一点的覆盖数不大于k
     

    Solution

    贪心策略,从左往右找每个需要删区间的点,对于区间选择采取满足l<=i且r最大
    由于区间和n值较小,O(n^3)亦可过
      1 /*
      2     给n个区间,一个上界k
      3     问最少删除多少区间,使得区间内任一点的覆盖数不大于k
      4     贪心策略,从左往右找每个需要删区间的点,对于区间选择采取满足l<=i且r最大
      5     由于区间和n值较小,O(n^3)亦可过
      6 */
      7 #include <algorithm>
      8 #include <cctype>
      9 #include <cmath>
     10 #include <cstdio>
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <iostream>
     14 #include <map>
     15 #include <numeric>
     16 #include <queue>
     17 #include <set>
     18 #include <stack>
     19 #if __cplusplus >= 201103L
     20 #include <unordered_map>
     21 #include <unordered_set>
     22 #endif
     23 #include <vector>
     24 #define lson rt << 1, l, mid
     25 #define rson rt << 1 | 1, mid + 1, r
     26 #define LONG_LONG_MAX 9223372036854775807LL
     27 #define ll LL
     28 using namespace std;
     29 typedef long long ll;
     30 typedef long double ld;
     31 typedef unsigned long long ull;
     32 typedef pair<int, int> P;
     33 int n, m, k;
     34 const int maxn = 1e5 + 10;
     35 template <class T>
     36 inline T read()
     37 {
     38     int f = 1;
     39     T ret = 0;
     40     char ch = getchar();
     41     while (!isdigit(ch))
     42     {
     43         if (ch == '-')
     44             f = -1;
     45         ch = getchar();
     46     }
     47     while (isdigit(ch))
     48     {
     49         ret = (ret << 1) + (ret << 3) + ch - '0';
     50         ch = getchar();
     51     }
     52     ret *= f;
     53     return ret;
     54 }
     55 template <class T>
     56 inline void write(T n)
     57 {
     58     if (n < 0)
     59     {
     60         putchar('-');
     61         n = -n;
     62     }
     63     if (n >= 10)
     64     {
     65         write(n / 10);
     66     }
     67     putchar(n % 10 + '0');
     68 }
     69 template <class T>
     70 inline void writeln(const T &n)
     71 {
     72     write(n);
     73     puts("");
     74 }
     75 struct node
     76 {
     77     int l, r, idx;
     78     node() {}
     79     node(int l, int r, int idx)
     80     {
     81         this->l = l, this->r = r, this->idx = idx;
     82     }
     83     bool operator<(const node &t1) const
     84     {
     85         if (r == t1.r)
     86             return l < t1.l;
     87         return r < t1.l;
     88     }
     89 };
     90 
     91 vector<node> vec;
     92 int p[202], del[202];
     93 int main(int argc, char const *argv[])
     94 {
     95 #ifndef ONLINE_JUDGE
     96     freopen("in.txt", "r", stdin);
     97     // freopen("out.txt", "w", stdout);
     98 #endif
     99     n = read<int>(), k = read<int>();
    100     int maxx = 0;
    101     for (int i = 1; i <= n; i++)
    102     {
    103 
    104         int x = read<int>(), y = read<int>();
    105         maxx = max(maxx, y);
    106         vec.emplace_back(x, y, i);
    107         for (int j = x; j <= y; j++)
    108             ++p[j];
    109     }
    110     for (int i = 1; i <= maxx; i++)
    111     {
    112         while (p[i] > k)
    113         {
    114             int rr = 0, delid = -1;
    115             for (int j = 0; j < n; j++)
    116                 if (!del[j] && vec[j].l <= i && vec[j].r > rr)
    117                 {
    118                     rr = vec[j].r;
    119                     delid = j;
    120                 }
    121             for (int j = vec[delid].l; j <= vec[delid].r; j++)
    122                 --p[j];
    123             del[delid] = 1;
    124         }
    125     }
    126     int res = accumulate(del, del + n, 0);
    127     writeln(res);
    128     for (int i = 0; i < n; i++)
    129         if (del[i])
    130             write(i + 1), putchar(' ');
    131     return 0;
    132 }
    View Code

    D2. Too Many Segments

    Description

    同上一题

    Solution

    官方题解没看懂,看了大佬博客得知的贪心思路。

    要想最少删减区间,则要使删减的区间尽可能的大,留下的区间尽可能少重叠(感觉前一句话更好理解)。

    考虑区间右端点排序,线段树维护区间最大值,询问一个区间时,如果当前区间加上后最值小于k说明可以加入,否则加入删除边集。

    为什么右端点排序时正确的呢,右端点排序后,相同右端点的区间中一定是左端点最小的首先出现,且此时大概率会出现当前区间覆盖之前已访问区间的情况,

    也就是说,此时的区间一定是当前右端点最长的一个,且和前面区间很大可能重叠。这时线段树查询区间最值,如果大于等于k说明不能满足,删除这条边就是贪心最优策略。

      1 #include <algorithm>
      2 #include <cctype>
      3 #include <cmath>
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <iostream>
      8 #include <map>
      9 #include <queue>
     10 #include <set>
     11 #include <stack>
     12 #if __cplusplus >= 201103L
     13 #include <unordered_map>
     14 #include <unordered_set>
     15 #endif
     16 #include <vector>
     17 #define lson rt << 1
     18 #define rson rt << 1 | 1
     19 #define LONG_LONG_MAX 9223372036854775807LL
     20 #define pblank putchar(' ')
     21 #define ll LL
     22 using namespace std;
     23 typedef long long ll;
     24 typedef long double ld;
     25 typedef unsigned long long ull;
     26 typedef pair<int, int> P;
     27 int n, m, k;
     28 const int maxn = 2e5 + 10;
     29 template <class T>
     30 inline T read()
     31 {
     32     int f = 1;
     33     T ret = 0;
     34     char ch = getchar();
     35     while (!isdigit(ch))
     36     {
     37         if (ch == '-')
     38             f = -1;
     39         ch = getchar();
     40     }
     41     while (isdigit(ch))
     42     {
     43         ret = (ret << 1) + (ret << 3) + ch - '0';
     44         ch = getchar();
     45     }
     46     ret *= f;
     47     return ret;
     48 }
     49 template <class T>
     50 inline void write(T n)
     51 {
     52     if (n < 0)
     53     {
     54         putchar('-');
     55         n = -n;
     56     }
     57     if (n >= 10)
     58     {
     59         write(n / 10);
     60     }
     61     putchar(n % 10 + '0');
     62 }
     63 template <class T>
     64 inline void writeln(const T &n)
     65 {
     66     write(n);
     67     puts("");
     68 }
     69 struct node
     70 {
     71     int l, r, idx;
     72     node() {}
     73     node(int ll, int rr, int i) : l(ll), r(rr), idx(i) {}
     74     bool operator<(const node &t) const
     75     {
     76         if (r == t.r)
     77             return l < t.l;
     78         return r < t.r;
     79     }
     80 };
     81 vector<node> vec;
     82 struct Node
     83 {
     84     int l, r;
     85     ll sum, lazy;
     86 } tr[maxn << 2];
     87 inline void pushup(int rt)
     88 {
     89     tr[rt].sum = max(tr[lson].sum, tr[rson].sum);
     90 }
     91 inline void pushdown(int rt)
     92 {
     93 
     94     if (tr[rt].lazy)
     95     {
     96         tr[lson].lazy += tr[rt].lazy; //注意此题是区间加,固懒标记也应该是累加而不是覆盖
     97         tr[rson].lazy += tr[rt].lazy;
     98         tr[lson].sum += tr[rt].lazy;
     99         tr[rson].sum += tr[rt].lazy;
    100         tr[rt].lazy = 0;
    101     }
    102 }
    103 void build(int rt, int l, int r)
    104 {
    105     tr[rt].l = l;
    106     tr[rt].r = r;
    107     tr[rt].lazy = tr[rt].sum = 0;
    108     if (l == r)
    109         return;
    110     int mid = l + r >> 1;
    111     build(lson, l, mid);
    112     build(rson, mid + 1, r);
    113 }
    114 void update(int rt, int L, int R, ll v)
    115 {
    116     int l = tr[rt].l;
    117     int r = tr[rt].r;
    118     if (l >= L && r <= R)
    119     {
    120         tr[rt].lazy += v;
    121         tr[rt].sum += v;
    122         return;
    123     }
    124     pushdown(rt); //当前区间没有在之前返回代表当前区间并非包含于待查询区间,在向左右区间查询时需要先将懒标记下放
    125     int mid = l + r >> 1;
    126     if (L <= mid)
    127         update(lson, L, R, v);
    128     if (R > mid)
    129         update(rson, L, R, v);
    130     pushup(rt); //更新父区间
    131 }
    132 ll query(int rt, int L, int R)
    133 {
    134     int l = tr[rt].l;
    135     int r = tr[rt].r;
    136     if (l >= L && r <= R)
    137         return tr[rt].sum;
    138     pushdown(rt); //和update同理
    139     int mid = l + r >> 1;
    140     ll ans = 0;
    141     if (L <= mid)
    142         ans = max(ans, query(lson, L, R));
    143     if (R > mid)
    144         ans = max(ans, query(rson, L, R));
    145     return ans;
    146 }
    147 int main(int argc, char const *argv[])
    148 {
    149 #ifndef ONLINE_JUDGE
    150     freopen("in.txt", "r", stdin);
    151     // freopen("out.txt", "w", stdout);
    152 #endif
    153     n = read<int>(), k = read<int>();
    154     int maxx = 0;
    155     for (int i = 0; i < n; i++)
    156     {
    157         int x = read<int>(), y = read<int>();
    158         vec.emplace_back(x, y, i + 1);
    159         maxx = max(maxx, y);
    160     }
    161     sort(vec.begin(), vec.end());
    162     build(1, 1, maxx);
    163     vector<int> res;
    164     for (int i = 0; i < n; i++)
    165     {
    166         int cur = query(1, vec[i].l, vec[i].r);
    167         if (cur < k)
    168             update(1, vec[i].l, vec[i].r, 1);
    169         else
    170             res.emplace_back(vec[i].idx);
    171     }
    172     sort(res.begin(), res.end());
    173     writeln(res.size());
    174     for (int x : res)
    175         write(x), pblank;
    176     return 0;
    177 }
    View Code

    E. By Elevator or Stairs?

    Description

     Solution

    简单dp

    dp[i][0]表示走路到i层的最小花费,dp[i][1]表示电梯到i层的最小花费。

    考虑状态转移

    需要注意dp[2]是一开始就确定的,wa了一发

     1 #include <algorithm>
     2 #include <cctype>
     3 #include <cmath>
     4 #include <cstdio>
     5 #include <cstdlib>
     6 #include <cstring>
     7 #include <iostream>
     8 #include <map>
     9 #include <queue>
    10 #include <set>
    11 #include <stack>
    12 #if __cplusplus >= 201103L
    13 #include <unordered_map>
    14 #include <unordered_set>
    15 #endif
    16 #include <vector>
    17 #define lson rt << 1, l, mid
    18 #define rson rt << 1 | 1, mid + 1, r
    19 #define LONG_LONG_MAX 9223372036854775807LL
    20 #define ll LL
    21 using namespace std;
    22 typedef long long ll;
    23 typedef long double ld;
    24 typedef unsigned long long ull;
    25 typedef pair<int, int> P;
    26 int n, m, k;
    27 const int maxn = 2e5 + 10;
    28 template <class T>
    29 inline T read()
    30 {
    31     int f = 1;
    32     T ret = 0;
    33     char ch = getchar();
    34     while (!isdigit(ch))
    35     {
    36         if (ch == '-')
    37             f = -1;
    38         ch = getchar();
    39     }
    40     while (isdigit(ch))
    41     {
    42         ret = (ret << 1) + (ret << 3) + ch - '0';
    43         ch = getchar();
    44     }
    45     ret *= f;
    46     return ret;
    47 }
    48 template <class T>
    49 inline void write(T n)
    50 {
    51     if (n < 0)
    52     {
    53         putchar('-');
    54         n = -n;
    55     }
    56     if (n >= 10)
    57     {
    58         write(n / 10);
    59     }
    60     putchar(n % 10 + '0');
    61 }
    62 template <class T>
    63 inline void writeln(const T &n)
    64 {
    65     write(n);
    66     puts("");
    67 }
    68 ll dp[maxn][2];
    69 ll a[maxn], b[maxn], c;
    70 int main(int argc, char const *argv[])
    71 {
    72 #ifndef ONLINE_JUDGE
    73     freopen("in.txt", "r", stdin);
    74     freopen("out.txt", "w", stdout);
    75 #endif
    76     n = read<int>(), c = read<int>();
    77     for (int i = 1; i < n; i++)
    78         a[i] = read<ll>();
    79     for (int i = 1; i < n; i++)
    80         b[i] = read<ll>();
    81     dp[2][1] = c + b[1];
    82     dp[2][0] = a[1];
    83     for (int i = 3; i <= n; i++)
    84     {
    85         dp[i][0] = min(dp[i - 1][1], dp[i - 1][0]) + a[i - 1];
    86         dp[i][1] = min(dp[i - 1][0] + c, dp[i - 1][1]) + b[i - 1];
    87     }
    88     for (int i = 1; i <= n; i++)
    89         write(min(dp[i][0], dp[i][1])), putchar(' ');
    90     return 0;
    91 }
    View Code

    F. Maximum Weight 

     

    Description

    给一棵n个结点的树,每条边权值为1,点权由题目给出。

    求一个最大点集的点权和,要求点集里任意两结点的距离大于k。

    solution

    树形dp想了半天没想出来是个five没错了。

    看到某聚聚用的逆序深度遍历求的结果。

    大概是先dfs一遍求出每个点深度,然后从深度最大的叶子结点开始搜索。

    每次加上当前选中的节点权值并将相邻k的节点的权值减去当前权值。

    只要节点权值大于0则证明选择此节点比选择之前的更新过当前节点的权值的那些节点更加优秀,由于之前也在累加答案,且当前节点的权值已经是被减过的,只要在答案上加上当前权值就行了。重复步骤。(也有点像最优子结构)

    为什么从叶子结点开始呢,我的理解是叶子结点在最外层,选择叶子结点能最大程度选择更多的点使得距离大于k,像是一种贪心思想。

  • 相关阅读:
    用PS设计一个简单的立体字
    Photoshop如何查看各种字体
    花生壳内网穿透
    mac版FTP
    根据平时的使用情况列出经常用的mac终端命令以便以后方便查找
    Text 组件的样式
    react-native 开发中遇到的坑
    react-native-swiper 使用遇到的坑
    详解intrinsicContentSize 及 约束优先级/content Hugging/content Compression Resistance
    WebStorm里面配置运行React Native的方案
  • 原文地址:https://www.cnblogs.com/mooleetzi/p/11728001.html
Copyright © 2020-2023  润新知