zoukankan      html  css  js  c++  java
  • codeforces round#509

    博主水平不高, 只能打完$4$题, QAQ什么时候才能变强啊嘤嘤嘤


    订正完6题了,  还想打今天下午的CF , 只能迟十分钟了, 掉分预定

    A. Heist

    输出 $max - min + n - 1$即可

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 using namespace std;
     6 
     7 const int N = 1e3 + 5;
     8 const int inf = ~0U >> 1;
     9 
    10 int n, a[N], x, maxn, minn = inf;
    11 
    12 int read () {
    13     int X = 0, p = 1; char c = getchar();
    14     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    15     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    16     return X * p;
    17 }
    18 
    19 int main()
    20 {
    21     n = rd;
    22     for(int i = 1; i <= n; ++i) {
    23         a[i] = rd;
    24         minn = min(minn, a[i]);
    25         maxn = max(maxn, a[i]);
    26     }
    27     printf("%d
    ", maxn - minn - n + 1);
    28 }
    Heist


    B. Buying a TV Set

    Description

    要求找出 $ i<=a, j<=b$ 并且 $ i : j = x : y$

    Solution

    先将$ x, y$约分, 输出$ min(i div x, j div y)$ 即可

    Code

     1 #include<cstdio>
     2 #define ll long long
     3 
     4 ll gcd(ll x, ll y) {
     5     return x % y ? gcd(y, x % y) : y;
     6 }
     7 
     8 int main()
     9 {
    10     ll a, b, x, y, d;
    11     scanf("%I64d%I64d%I64d%I64d", &a, &b, &x, & y);
    12     d = gcd(x, y);
    13     x /= d; y /= d;
    14     ll tmp1 = a / x, tmp2 = b / y;
    15     printf("%I64d
    ", tmp1 > tmp2 ? tmp2 : tmp1);
    16 }
    Buying a TV set

    C. Coffee Break

    Description

    主人公想要在$n$个时间点喝咖啡, 但是老板要求他 每次 喝咖啡 的 间隔 必须 $>=d$

    求问主人公至少要 几天 才能在 每个时间点 都喝过咖啡。

    Solution

    贪心 + 二分查找

    用Set写 复杂度更严格, 但是我没想到用Set删除。

    外层枚举到每一天$i$, 如果 $i$ 没有被确定在哪一天喝, 则 $++ans$, 并在第 $ans$(当前的ans) 天喝。

    接下来再查找出第一个$>=   a[i] + d + 1$的 时刻$j$,  如果$j$ 已经被确定在哪天喝, 那么$j++$, 直到$j > n $ 或 $j$ 没有被确定在哪一天喝。

    把 $j$ 和 $i$ 确定为同一天喝就可以惹。

    复杂度并不是严格的$O(nlogn)$, 希望不要呱

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 using namespace std;
     6 
     7 const int N = 2e5 + 5;
     8 
     9 int n, m, d, ans;
    10 int b[N];
    11 
    12 struct node {
    13     int pos, id, day;
    14 }a[N];
    15 
    16 int read() {
    17     int X = 0, p = 1; char c =getchar();
    18     for(;c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    19     for(;c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    20     return X * p;
    21 }
    22 
    23 int fd(int x) {
    24     return lower_bound(b + 1, b + 1 + n, x) - b;
    25 }
    26 
    27 int cmp1(const node &A, const node &B) {
    28     return A.pos < B.pos;
    29 }
    30 
    31 int cmp2(const node &A, const node &B) {
    32     return A.id < B.id;
    33 }
    34 
    35 int main()
    36 {
    37     n = rd; m = rd; d = rd;
    38     for(int i = 1; i <= n; ++i)
    39         b[i] = a[i].pos = rd, a[i].id = i;
    40     sort(b + 1, b + 1 + n);
    41     sort(a + 1, a + 1 + n, cmp1);
    42     for(int i = 1; i <= n; ++i) {
    43         if(!a[i].day) a[i].day = ++ans;
    44         int tmp = a[i].pos + d + 1;
    45         tmp = fd(tmp);
    46         while(a[tmp].day && tmp <= n) 
    47             tmp++;
    48         if(tmp <= n) a[tmp].day = a[i].day;
    49     }
    50     printf("%d
    ", ans);
    51     sort(a + 1, a + 1 + n, cmp2);
    52     printf("%d", a[1].day);
    53     for(int i = 2; i <= n; ++i)
    54         printf(" %d", a[i].day);
    55     puts("");
    56 }
    Coffee Break

    D. Glider

    Description

    求出从哪一点开始下飞机, 滑翔的水平距离最远。 在上升气流的区间内 水平飞行, 在其他地方会 $1 : 1$地 下降

    并且输入的 上升气流的区间不重合、且递增。

    Solution

    官方题解 二分 + 前缀和

    我打出了个倍增。。。

    定义$nxt[i][j]$ 为 $i$ 之后的 第 $2^j$ 个区间(这不是可以直接$O(1)$算吗??? 我怎么知道我当时怎么想的。。。

           $dis[i][j]$ 为 $i$ 到 之后第 $2 ^ j$ 个区间 的空隙长度(即没有上升气流的长度)。

      $sum[i] $为前 $i$ 个上升气流的总长度

    由于空隙长度 必须 $ <= h$, 所以可以倍增求出最远到哪个区间。

    然后枚举下飞机的区间, 倍增求出最远到达的区间, 前缀和查询 上升气流长度 并更新答案。

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rd read()
     5 using namespace std;
     6 
     7 const int N = 2e5 + 5;
     8 const int base = 19;
     9 
    10 int l[N], r[N], h, n, maxn = h, sum[N];
    11 int dis[N][20], nxt[N][20];
    12 
    13 int read() {
    14     int X = 0, p = 1; char c = getchar();
    15     for(;c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    16     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    17     return X * p;
    18 }
    19 
    20 void cal(int now) {
    21     int rest = h, tmp = now;
    22     for(int k = base; ~k; --k)
    23         if(nxt[tmp][k] && rest - dis[tmp][k] > 0)
    24             rest -= dis[tmp][k], tmp = nxt[tmp][k];
    25     maxn = max(maxn, h + sum[tmp] - sum[now - 1]);
    26 }
    27 
    28 int main()
    29 {
    30     n = rd; h = rd;
    31     for(int i = 1; i <= n; ++i)
    32         l[i] = rd, r[i] = rd;
    33     for(int i = 1; i <= n; ++i)
    34         sum[i] = sum[i - 1] + r[i] - l[i];
    35     for(int i = 1; i < n; ++i) {
    36         dis[i][0] = l[i + 1] - r[i];
    37         nxt[i][0] = i + 1;
    38     }
    39     for(int k = 1; k <= base; ++k)
    40         for(int i = 1; i <= n; ++i) {
    41             nxt[i][k] = nxt[nxt[i][k - 1]][k - 1];
    42             dis[i][k] = dis[i][k - 1] + dis[nxt[i][k - 1]][k - 1];
    43         }
    44     for(int i = 1; i <= n; ++i) cal(i);
    45     printf("%d
    ", maxn);
    46 }
    Glider

    之后的就不会噜


    upd

    订正了一波。

    E. Tree Reconstruction

    Solution

    显然, 输入中的 $b$ 肯定等于$N$, 否则就一定不存在这样的一棵树。

    对于每个节点 $i$ $(i < n)$ , 它在输入中出现的次数为 $cnt[i]$, 那么 对于每个 $k$ , $cnt[1] + cnt[2] ... + cnt[k] <= k$ , 否则就不存在。

    然后就构造一条链, 一端是$N$, 另一端通过算法来补全。

    依次枚举$i$, 如果$cnt[i] == 0$, 那么把它继续留在$Set$里面, 到之后用。

    如果$cnt[i] > 0$, 那么 把 $i$ 添到链中, 因为在 $i$ 之前添入链中的节点编号都 $ < i$, 也就是对 $i$ 不产生贡献。

      接着往 链中添入 $cnt[i] - 1$ 个节点(这些节点的编号可以保证都 $< i$) 。

    枚举结束后再将 $N$ 与最后一个添入的节点连边

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<set>
     4 #define rd read()
     5 using namespace std;
     6 
     7 const int N = 1e5 + 5;
     8 
     9 int cnt[N], n;
    10 
    11 set<int>st;
    12 
    13 int read() {
    14     int X = 0, p = 1; char c = getchar();
    15     for(;c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    16     for(;c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    17     return X * p;
    18 }
    19 
    20 int main()
    21 {
    22     n = rd;
    23     for(int i = 1; i < n; ++i) {
    24         int u = rd, v = rd;
    25         if(v != n) return puts("NO"), 0;
    26         cnt[u]++;
    27     }
    28     int cur = 0;
    29     for(int i = 1; i < n; ++i) 
    30         if((cur += cnt[i]) > i)
    31             return puts("NO"), 0;
    32     for(int i = 1; i < n; ++i)
    33         st.insert(i);
    34     puts("YES");
    35     int last = 0;
    36     for(int i = 1; i < n; ++i) {
    37         if(cnt[i]) {
    38             st.erase(i);
    39             if(last)
    40                 printf("%d %d
    ", last, i);
    41             cnt[i]--;
    42             last = i;
    43         }
    44         while(cnt[i]) {
    45             printf("%d %d
    ", last, *st.begin());
    46             last = *st.begin();
    47             cnt[i]--;
    48             st.erase(*st.begin());
    49         }
    50     }
    51     printf("%d %d
    ", last, n);
    52 }
    Tree Reconstruction

    F. Ray in the tube

    感觉题解写的非常靠谱|清楚 , 题解传送门

    Solution

    设$A,  B$ 两点的水平距离为 $d$

    要使传感器感应到同一条光, 那么就要满足

    在第一条线上 : $a_i = a_j (mod 2d)$

    在第二条线上:  $b_i = b_j = a_k + d (mod   2d)$( $a$ 表示第一条线上的点, $b$ 表示第二条线上的点)

    有一个神奇的结论: 要使其方案最优, 必定有$d = 2^i$ $(i >= 0$)。

    反证 : 假如 $ d = k * 2^i$ ($k$ 为奇数), 那么它到达的点, $2^i$ 同样也能到达, 并且$2^i$ 所能到达的点更多。

    然后我们就枚举$d$ ($log1e9$种可能), 用 $MAP$ 记录 $a_i mod 2d$, 和 $(b_i + d) mod 2d$, 并在记录中更新答案。

    总复杂度 $O(NlogNlog1e9)$

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<map>
     5 #define rd read()
     6 using namespace std;
     7 
     8 const int N = 1e5 + 15;
     9 
    10 map<int, int> M;
    11 
    12 int a[N], b[N], n, m, maxn = 2;
    13 
    14 int read() {
    15     int X = 0, p = 1; char c = getchar();
    16     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
    17     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
    18     return X * p;
    19 }
    20 
    21 int main()
    22 {
    23     n = rd; rd;
    24     for(int i = 1; i <= n; ++i)
    25         a[i] = rd;
    26     m = rd; rd;
    27     for(int i = 1; i <= m; ++i)
    28         b[i] = rd;
    29     for(int tmp = 1; tmp <= 1e9; tmp <<= 1) {
    30         M.clear();
    31         for(int i = 1; i <= n; ++i) {
    32             int k = a[i] % (tmp << 1);
    33             if(!M.count(k)) M[k] = 1;
    34             else {maxn = max(maxn, ++M[k]);}
    35         }
    36         for(int i = 1; i <= m; ++i) {
    37             int k = (1LL * b[i] + tmp) % (tmp << 1);
    38             if(!M.count(k)) M[k] = 1;
    39             else {maxn = max(maxn, ++M[k]);}
    40         }
    41     }
    42     printf("%d
    ", maxn);
    43 }
    Ray in the tube
  • 相关阅读:
    Android 中Service生命周期
    Android开发中退出程序几种方法
    FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_REORDER_TO_FRONT用法
    【Java并发编程实战】-----synchronized
    The specified child already has a parent错误
    使用Ant打包工具 基本介绍
    what's WSDL
    XFire WebService demo
    jws webservice code
    axis、xfire、CXF 、JWS
  • 原文地址:https://www.cnblogs.com/cychester/p/9657450.html
Copyright © 2011-2022 走看看