zoukankan      html  css  js  c++  java
  • codeforces Educational Round 89


    A、Shovels and Swords

    题意:

    两个木棍一个钻石做一把钻石铲,一个木棍两个钻石做一把钻石剑,现在有$a$个木棍,$b$各位钻石,求最多能做多少钻石工具?

    题解:

    如果两个恰好用完,直接列方程组求解得$frac {a+b}{3}$,如果有一种东西剩下来了,那么答案就是另一个的数量,所以最终的答案是$min(frac {a+b}{3}, a, b)$。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N = 1e5 + 5;
     4 typedef long long ll;
     5 typedef pair<int, int> pii;
     6 void solve()
     7 {
     8     int a, b;
     9     scanf("%d%d", &a, &b);
    10     printf("%d
    ", min((a + b) / 3, min(a, b)));
    11 }
    12 int main()
    13 {
    14     int T;
    15     scanf("%d", &T);
    16     while (T--)
    17         solve();
    18     return 0;
    19 }
    View Code

    B、Shuffle

    题意:

    给出一个数组长度是$n$,其中$a_x$是$1$,其他都是$0$,给出$m$个操作,每个操作给出我范围$l$,$r$,你可以任意选择两个范围内的位置,可以是一样的位置,然后交换其值,求这$m$个操作结束后,有多少个位置的值是可以变成$1$的。

    题解:

    首先之前的操作结束后,只要$1$可能到达的位置范围和这次询问的范围有交集,那么显然这次操作的整个范围$1$都是可达的,所以如果之前$1$可以到达的范围和这次操作的范围有交集,则可达范围变成这两个范围的并集,如果没有交集则直接丢弃。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N = 1e5 + 5;
     4 typedef long long ll;
     5 typedef pair<int, int> pii;
     6 void solve()
     7 {
     8     int n, x, m;
     9     scanf("%d%d%d", &n, &x, &m);
    10     int ql, qr, l, r;
    11     ql = qr = x;
    12     for (int i = 1; i <= m; ++i)
    13     {
    14         scanf("%d%d", &l, &r);
    15         if (ql > r || qr < l)
    16             continue;
    17         ql = min(ql, l);
    18         qr = max(qr, r);
    19     }
    20     printf("%d
    ", qr - ql + 1);
    21 }
    22 int main()
    23 {
    24     int T;
    25     scanf("%d", &T);
    26     while (T--)
    27         solve();
    28     return 0;
    29 }
    View Code

    C、Palindromic Paths

    题意:

    给出一个$01$矩阵,一个人从$(1,1)$出发到达$(n,m)$,只能向右或者向下。他走过地方(包括起点终点)会形成一个$01$串,求最少改变多少个位置,使得这个人走过的所有路径形成的串都是回文串。

    题解:

    我们画出矩阵中走到某一步可能的位置发现:$i+j=const$,所以为了保证回文,所以正数第$k$步和倒数第$k$步的所有字符都必须一样。这样子我们就可以开个桶,统计$1$的数量,然后就可以顺便推出$0$的数量,取小的值加到答案中。然后注意到,如果路径长度是奇数,那么最中间的一步的字符是任意的,如果是偶数,那么最中间的两步的字符也一定要一样。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N = 1e5 + 5;
     4 typedef long long ll;
     5 typedef pair<int, int> pii;
     6 int buc[105];
     7 void solve()
     8 {
     9     memset(buc, 0, sizeof(buc));
    10     int n, m, a;
    11     scanf("%d%d", &n, &m);
    12     for (int i = 1; i <= n; ++i)
    13         for (int j = 1; j <= m; ++j)
    14         {
    15             scanf("%d", &a);
    16             buc[i + j] += a;
    17         }
    18     int ans = 0;
    19     for (int i = 2; i <= (n + m) / 2; ++i)
    20     {
    21         int one = buc[i] + buc[n + m - i + 2];
    22         int size;
    23         if (i <= min(n, m))
    24             size = (i - 1) * 2;
    25         else
    26             size = min(n, m) * 2;
    27         ans += min(one, size - one);
    28     }
    29     if ((n + m) % 2 == 1)
    30     {
    31         int size = min(n, m) * 2;
    32         int one = buc[(n + m) / 2 + 1] + buc[(n + m) / 2 + 2];
    33         ans += min(one, size - one);
    34     }
    35     printf("%d
    ", ans);
    36 }
    37 int main()
    38 {
    39     int T;
    40     scanf("%d", &T);
    41     while (T--)
    42         solve();
    43     return 0;
    44 }
    View Code

    D、Two Divisors

    题意:

    给出$n$个数,对每个数$a_i$,求出一个$pair(d_1,d_2)$,满足$d_1>1$且$d_2>1$且$gcd(d_1+d_2,a_i)=1$,或者输出$(-1,-1)$表示没有。

    题解:

    解法一:

    考虑$gcd$的性质:$gcd(d_1,d_2) = 1$,则$gcd(d_1 imes d_2, d_1+d_2) = gcd(d_1,d_1+d_2) imes gcd(d_2,d_1+d_2) = 1$,所以我们暴力地找即可。显然,这个$a_i$是素数的时候或者只有一个质因数,一定找不到。

    AC代码(加上了记忆化):

     1 #include <bits/stdc++.h>
     2 #include <unordered_map>
     3 using namespace std;
     4 const int N = 5e5 + 5;
     5 typedef long long ll;
     6 typedef pair<int, int> pii;
     7 const int M = 1e7 + 5;
     8 bool isp[M];
     9 int p[M], tot;
    10 void init()
    11 {
    12     memset(isp, 0x3f, sizeof(isp));
    13     for (int i = 2; i < M; ++i)
    14     {
    15         if (isp[i])
    16             p[++tot] = i;
    17         for (int j = 1; j <= tot && p[j] * i < M; ++j)
    18         {
    19             isp[p[j] * i] = 0;
    20             if (i % p[j] == 0)
    21                 break;
    22         }
    23     }
    24 }
    25 int a[N];
    26 pii ans[N];
    27 int fac[N], top;
    28 int n = 1000;
    29 int gcd(int a, int b)
    30 {
    31     return !b ? a : gcd(b, a % b);
    32 }
    33 pii get_fac(int x)
    34 {
    35     for (int i = 2; i * i <= x; ++i)
    36         if (x % i == 0 && gcd(i, x / i) == 1)
    37             return {i, x / i};
    38     return {-1, -1};
    39 }
    40 unordered_map<int, pii> mp;
    41 void solve()
    42 {
    43     scanf("%d", &n);
    44     for (int i = 1; i <= n; ++i)
    45         scanf("%d", &a[i]);
    46     for (int i = 1; i <= n; ++i)
    47     {
    48         if (isp[a[i]])
    49             ans[i] = {-1, -1};
    50         else
    51         {
    52             if (mp.find(a[i]) == mp.end())
    53             {
    54                 get_fac(a[i]);
    55                 if (top == 1)
    56                     ans[i] = {-1, -1};
    57                 else
    58                     ans[i] = get_fac(a[i]);
    59                 mp[a[i]] = ans[i];
    60             }
    61             else
    62                 ans[i] = mp[a[i]];
    63         }
    64     }
    65     for (int i = 1; i <= n; ++i)
    66         printf("%d%c", ans[i].first, " 
    "[i == n]);
    67     for (int i = 1; i <= n; ++i)
    68         printf("%d%c", ans[i].second, " 
    "[i == n]);
    69 }
    70 int main()
    71 {
    72     init();
    73     int T = 1;
    74     //scanf("%d", &T);
    75     while (T--)
    76         solve();
    77     return 0;
    78 }
    View Code

    解法二:

    上面的$gcd$性质有点难想,我们可以换个想法,设$p_1$是$a_i$最小的质因数,设$a_i=x imes p_1^k$,我们令$d_1=p_1^k,d2=x$,如果其中一个是$1$就是找不到,素数也找不到。正确性显然。

    注:代码中的欧拉筛是完整功能的欧拉筛,$pm[i]$是$i$的最小质因子,$pk[i]$是这个最小质因子的幂次$k$,满足$i\%pm[i]^k==0$且$i\%pm[i]^{k+1}!=0$。

    AC代码(加上了记忆化):

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<int, int> pii;
     4 const int M = 1e7 + 5;
     5 const int N = 5e5 + 5;
     6 bool isp[M];
     7 int p[M], pm[M], ps[M];
     8 int tot;
     9 void get_p()
    10 {
    11     memset(isp, 0xff, sizeof(isp));
    12     for (int i = 2; i < M; ++i)
    13     {
    14         if (isp[i])
    15             p[++tot] = pm[i] = ps[i] = i;
    16         for (int j = 1; j <= tot; ++j)
    17         {
    18             int tmp = i * p[j];
    19             if (tmp >= M)
    20                 break;
    21             isp[tmp] = 0;
    22             pm[tmp] = p[j];
    23             if (i % p[j])
    24                 ps[tmp] = p[j];
    25             else
    26             {
    27                 ps[tmp] = ps[i] * p[j];
    28                 break;
    29             }
    30         }
    31     }
    32 }
    33 int a[N];
    34 pii ans[N];
    35 void solve()
    36 {
    37     get_p();
    38     int n;
    39     scanf("%d", &n);
    40     for (int i = 1; i <= n; ++i)
    41         scanf("%d", &a[i]);
    42     for (int i = 1; i <= n; ++i)
    43     {
    44         if (isp[a[i]] || a[i] == ps[a[i]])
    45             ans[i] = { -1,-1 };
    46         else
    47         {
    48             int tmp = a[i];
    49             ans[i].first = pm[tmp];
    50             tmp /= ps[tmp];
    51             ans[i].second = 1;
    52             while (tmp != 1)
    53             {
    54                 ans[i].second *= pm[tmp];
    55                 tmp /= ps[tmp];
    56             }
    57         }
    58     }
    59     for (int i = 1; i <= n; ++i)
    60         printf("%d%c", ans[i].first, " 
    "[i == n]);
    61     for (int i = 1; i <= n; ++i)
    62         printf("%d%c", ans[i].second, " 
    "[i == n]);
    63 }
    64 int main()
    65 {
    66     int T = 1;
    67     //scanf("%d", &T);
    68     while (T--)
    69         solve();
    70     return 0;
    71 }
    View Code

    E、Two Arrays

    题意:

    题解:

    AC代码:

  • 相关阅读:
    vue cli3使用官方方法配置sass全局变量报错ValidationError: Invalid options object. Sass Loader has been initialised using an options object that does not match the API schema.
    面试必备:HashMap、Hashtable、ConcurrentHashMap的原理与区别
    Lombok介绍、使用方法和总结
    位运算
    【ZooKeeper系列】3.ZooKeeper源码环境搭建
    【ZooKeeper系列】2.用Java实现ZooKeeper API的调用
    【ZooKeeper系列】1.ZooKeeper单机版、伪集群和集群环境搭建
    弄明白CMS和G1,就靠这一篇了
    面试官,不要再问我三次握手和四次挥手
    【面试必备】小伙伴栽在了JVM的内存分配策略。。。
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/13109714.html
Copyright © 2011-2022 走看看