zoukankan      html  css  js  c++  java
  • Codeforces Round #643 (Div. 2) A

    A. Sequence with Digits

    (Description:)

      定义: (a_{n + 1} = a_n + minDigit(a_n) imes maxDigit(a_n))

      给定 (a_1)(k),求 (a_k)

    (Solution:)

      显然当 (a_n) 中包含了 (0) 时,之后的数都等于 (a_n)。那么我们就要判断是否一定会出现包含 (0) 的情况,并且复杂度是可以接受的。

      首先 (minDigit(x) imes maxDigit(x) leq 81)。那么令 (t = x mod 1000),那么 (t < 1000),那么在经过递增过后,一定会出现 (t + m geq 1000),由于 (m leq 81),那么 (t + m < 1100),也就是一千零几,那么他的百位一定是 (0)。所以我们是可以直接循环去解决。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    
    ll calc(ll num){
        ll Min = 9, Max = 0;
        while(num){
            Min = min(Min, num % 10);
            Max = max(Max, num % 10);
            num /= 10;
        }
        return Min * Max;
    }
    
    int main(){
        int t; cin >> t;
        while(t --){
            ll a, k;
            cin >> a >> k;
            for(int i = 2; i <= k; i ++){
                a = a + calc(a);
                if(calc(a) == 0) break;
            }
            cout << a << endl;
        }
        return 0;
    }
    



    B. Young Explorers

    (Description:)

      给定长度为 (n) 的数组 (e),进行分组,要求 (e_i leq) 该组的人数,问最多分几组?

    (Solution:)

      从小到大排个序,从左边到右边遍历一遍,能组成一组就组成一组。

    (Code:)

    //http://codeforces.com/contest/1355/problem/B
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    const double PI  = acos(-1.0);
    const double eps = 1e-8;
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f;
    inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
    inline ll  gcd(ll  a, ll b)  { return b ? gcd(b, a % b) : a; }
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    const int N = 3e5 + 10;
    
    int e[N];
    
    int main(){
    
        int t; cin >> t;
        while(t --){
            int n; cin >> n;
            for(int i = 1; i <= n; i ++)
                scanf("%d", &e[i]);
            sort(e + 1, e + n + 1);
            int ans = 0;
            int cnt = 0; // 记录当前组的人数
            for(int i = 1; i <= n; i ++){
                cnt ++;
                if(e[i] <= cnt){ // 符合要求了
                    cnt = 0;
                    ans ++;
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    
    



    C. Count Triangles

    (Description:)

      给定 (a, b, c, d),问有多少组 ((x, y, z)) 构成三角形,要求满足:(aleq xleq bleq yleq cleq zleq d)

    (Solution:)

      枚举 (x),由于 (x + y > z) 并且 (z geq c),那么 (y_{min} = max(b, c - x + 1)) 才能符合要求;当 (x + y > d) 之后,(z) 的选择始终为 (d - c + 1) 个,那么我们计算出 (y_{max} = max(b, d - x + 1))。那么我们就可以分两段计算:([y_{min}, y_{max} - 1])([y_{max}, c])

      对于 ([y_{min}, y_{max} - 1])(sum_{i = y_{min}}^{y_{max}-1} (x + y_i - c))((x + y_i - c)) 就是 (z) 可以选择的个数。而这显然是等差数列求和。

      对于 ([y_{max}, c])((c - y_{max} + 1) imes (d - c + 1))

    (Code:)

    //http://codeforces.com/contest/1355/problem/C
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    const double PI  = acos(-1.0);
    const double eps = 1e-8;
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f;
    inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
    inline ll  gcd(ll  a, ll b)  { return b ? gcd(b, a % b) : a; }
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    int main(){
    
        // a <= x <= b <= y <= c <= z <= d
    
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
    
        ll ans = 0;
        for(ll x = a; x <= b; x ++){
            ll yMin = max(b, c - x + 1);
            ll yMax = max(b, d - x + 1);
            ans += max(c - yMax + 1, 1ll * 0) * (d - c + 1); // 有可能 yMax > c
            yMax = min(yMax - 1, c);
            ans += (yMax - yMin + 1) * (2 * (x - c) + yMin + yMax) / 2;
        }
    
        cout << ans << endl;
    
    
        return 0;
    }
    
    



    D. Game With Array

    (Description:)

      能否构造出一个数组,使得数组中任意一段区间的和不为 (k)(s - k)(s) 为数组的和。( (k) 自选)

    (Solution:)

      对于 (n = 1) 的情况很容易判断。

      对于 (n geq 2):构造出不含 (1) 的数组,令 (k = 1) 即可符合要求。那么也就是数组每一项最少为 (2),也就是说 (s leq 2 imes n - 1) 的不行。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    const double PI  = acos(-1.0);
    const double eps = 1e-8;
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f;
    inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
    inline ll  gcd(ll  a, ll b)  { return b ? gcd(b, a % b) : a; }
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    
    int main(){
        
        int n, s;
        cin >> n >> s;
        if(n == 1){
            if(s == 1) puts("NO");
            else{
                puts("YES");
                cout << s << endl;
                cout << s - 1 << endl;
            }
        }else{
            if(s <= 2 * n - 1) puts("NO");
            else{
                puts("YES");
                for(int i = 1; i < n; i ++)
                    printf("2 ");
                cout << s - 2 * (n - 1) << endl;
                cout << 1 << endl;
            }
        }
        return 0;
    }
    
    



    E. Restorer Distance

    (Description:)

      给出长度为 (n) 的数组 (h),要求使数组中的数都相同。

      有三种操作:

        (1.) 使某个数加 (1),花费 (a)

        (2.) 使某个数减 (1),花费 (r);

        (3.) 选择两个数,一个加 (1),一个减 (1),花费 (m)

      求最少代价?

    (Solution:)

      我们枚举最终的高度,可以想到的是代价一定是随高度变化的一个二次函数。那么直接三分就可以轻易求解。

    (Code:)

    //http://codeforces.com/contest/1355/problem/E
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    const double PI  = acos(-1.0);
    const double eps = 1e-8;
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f;
    inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
    inline ll  gcd(ll  a, ll b)  { return b ? gcd(b, a % b) : a; }
    inline int lcm(int a, int b) { return a * b / gcd(a, b); }
    
    const int N = 1e5 + 10;
    
    int n, a, r, m;
    int h[N];
    ll sum[N];
    
    ll check(int mid){
        ll more = 0, less = 0;
        for(int i = 1; i <= n; i ++){
            if(h[i] < mid) less += mid - h[i];
            if(h[i] > mid) more += h[i]- mid;
        }
        ll res = min(less, more) * m;
        if(less > more) res += a * (less  - more);
        else res += r * (more - less);
        return res;
    }
    
    int main(){
    
        cin >> n >> a >> r >> m;
        for(int i = 1; i <= n; i ++)
            scanf("%d", &h[i]);
        sort(h + 1, h + n + 1);
    
        m = min(m, a + r);
    
        int le = h[1], ri = h[n];
        ll ans = LNF;
        while(le <= ri){
            int lmid = le + (ri - le) / 3;
            int rmid = ri - (ri - le) / 3;
            ll costl = check(lmid);
            ll costr = check(rmid);
            if(costl < costr){
                ans = costl;
                ri = rmid - 1;
            }else{
                ans = costr;
                le = lmid + 1;
            }
        }
    
        cout << ans << endl;
        
        return 0;
    }
    
    



  • 相关阅读:
    memset使用技巧
    AcWing 843. n-皇后问题
    【Oracle】从12c开始支持的Oralce新分页方案
    Oracle历年版本发布情况
    【SpringBoot】又写了一份新瓶装旧酒的CRUD程序
    【SpringBoot/Actuator】给SpringBoot程序添加Actuator监控管理
    Top Cybersecurity Companies for 2021
    SNAT、DNAT、MASQUERADE的区别
    Flannel的两种模式解析(VXLAN、host-gw)
    kubelet 配置资源预留的姿势
  • 原文地址:https://www.cnblogs.com/nonameless/p/12912252.html
Copyright © 2011-2022 走看看