• Educational Codeforces Round 88 (Rated for Div. 2) A


    题目链接


    (A. Berland Poker)

    (Description:)
      给定 (n) 张牌,其中有 (m) 张特殊的牌,把所有牌平均分给 (k) 个人,问你手中的特殊牌的数量 (-(k - 1)) 个人中拥有最多特殊牌的数量的最大值是多少?
    (Solution:)
      先把特殊牌分给你,其他人在平均分即可。
    (Code:)

    /*
    @Author: nonameless
    @Date:   2020-05-29 09:20:42
    @Email:  2835391726@qq.com
    @Blog:   https://www.cnblogs.com/nonameless/
    */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    const double eps = 1e-8;
    const double PI  = acos(-1.0);
    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 t; cin >> t;
        while(t --){
            int n, m, k;
            cin >> n >> m >> k;
            int cnt = n / k;
            if(cnt >= m) cout << m << endl;
            else{
                cnt -= (m - cnt) / (k - 1) + ((m - cnt) % (k - 1) != 0);
                cout << cnt << endl;
            }
        }
        return 0;
    }
    
    

    (B. New Theatre Square)

    (Description:)
      给定 (n imes m) 的矩阵,让你来用 (1 imes 2)(1 imes 1) 的砖来填充矩阵中的 (.),砖只能横着放,问最小代价是多少?
    (Solution:)
      遍历每一行,算出连续的 (.) 的个数即可。
    (Code:)

    /*
    @Author: nonameless
    @Date:   2020-05-29 09:25:29
    @Email:  2835391726@qq.com
    @Blog:   https://www.cnblogs.com/nonameless/
    */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    const double eps = 1e-8;
    const double PI  = acos(-1.0);
    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 = 1e2 + 10, M = 1e3 + 10;
    
    int n, m, x, y;
    char s[N][M];
    
    int main(){
    
        int t; cin >> t;
        while(t --){
            cin >> n >> m >> x >> y;
            for(int i = 1; i <= n; i ++)
                scanf("%s", s[i] + 1);
            y = min(x + x, y);
    
            int ans = 0;
            for(int i = 1; i <= n; i ++){
    
                int cnt = 0;
                for(int j = 1; j <= m; j ++){
                    if(s[i][j] == '.') cnt ++;
                    else{
                        ans += cnt / 2 * y + (cnt % 2) * x;
                        cnt = 0;
                    }
                }
                ans += cnt / 2 * y + (cnt % 2) * x;
            }
            cout << ans << endl;
        }
        
        return 0;
    }
    
    

    (C. Mixing Water)

    (Description:)
      一杯热水的温度是 (h),一杯冷水的温度是 (c),按照热冷热冷热的顺序往桶里倒水,使其平均温度 (tb) 最接近 (t),问最少加几杯水?
    (Solution:)
      首先要知道的是如果我们加了偶数杯,也就是说热水和冷水各加了 (x) 杯,那么可以得到:(frac{x(h+c)}{2x} = frac{h+c}{2}),所以对于偶数杯的情况,就考虑完了。对于奇数杯,也就是在热冷各加了 (x) 杯后,再加了 (1) 杯热水,也就是说(设 (a = h + c)):

    [tb = frac{ax+h}{2x+1} = frac{frac{a}{2}(2x+1)+h-frac{a}{2}}{2x+1}=frac{a}{2}+frac{h-frac{a}{2}}{2x+1} ]

      由于 (h > frac{a}{2}),所以 (tb) 是关于 (x) 的递减函数,那么我们就可以二分解决了。
    (Code:)

    /*
    @Author: nonameless
    @Date:   2020-05-29 09:38:19
    @Email:  2835391726@qq.com
    @Blog:   https://www.cnblogs.com/nonameless/
    */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    const double eps = 1e-8;
    const double PI  = acos(-1.0);
    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 h, c, t;
    
    double calc(int cnt){ // 对于杯数下的平均温度
        int a = cnt / 2, b = cnt % 2;
        double res = (1ll * a * (h + c) + b * h) * 1.0 / cnt;
        return res; 
    }
    
    int main(){
    
        int test; cin >> test;
        while(test --){
            cin >> h >> c >> t;
    
            // first 是温度差,second 是杯数,优先按温度差排序
            vector<pair<double, int> > vec; 
    
            vec.pb({fabs((h + c) / 2.0 - t), 2}); 
            
            int l = 0, r = 1e9;
            int more = 1, less = 1; // 一个大于 t, 一个小于等于 t
            while(l <= r){
                int mid = l + r >> 1;
                int x = 2 * mid + 1; // 这样 x 就一定是奇数了
                double tb = calc(x); 
                if(tb > t){
                    more = x;
                    l = mid + 1;
                } else{
                    less = x;
                    r = mid - 1;
                }
            }
    
            vec.pb({fabs(t - calc(less)), less});
            vec.pb({fabs(t - calc(more)), more});
    
            sort(all(vec)); // 排序
            cout << vec[0].y << endl;
    
    
        }
        return 0;
    }
    
    

    (D. Yet Another Yet Another Task)

    (Description:)
      求某一段区间和减去区间的最大值后的所得得值最大可以是多少?特别得是 (-30 leq a_i leq 30)
    (Solution:)
      题目已经明示了我们可以选择区间的最大值得只有 ([1, 30])(如果区间的最大值为负,那么我们为了结果最大,我们只有选长度为 (1) 的区间),所以我们就可以去枚举我们选出的区间的最大值,然后遍历整个数组,只要区间在此处不中断就与结果取 (max)
    (Code:)

    /*
    @Author: nonameless
    @Date:   2020-05-29 14:32:55
    @Email:  2835391726@qq.com
    @Blog:   https://www.cnblogs.com/nonameless/
    */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    const double eps = 1e-8;
    const double PI  = acos(-1.0);
    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[N];
    
    int main(){
        
        cin >> n;
        for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    
        int ans = 0;
        for(int i = 1; i <= 30; i ++){
            int tmp = 0; // 连续的和
            for(int j = 1; j <= n; j ++){
                // 遇到比我们选择的区间最大值还大,就说明他一定不在我们所选的区间中,那么到这里区间就中断了,所以 tmp = 0;
                if(a[j] > i) tmp = 0; 
                else{
                    tmp = max(0, tmp + a[j]); // 如果到这里区间和为负,那么我们应该舍弃掉
                    ans = max(ans, tmp - i);
                }
            }
        }
    
        cout << ans << endl;
        
        return 0;
    }
    
    

    (E. Modular Stability)

    (Description:)
      给定 (n,k),让你构造一个长度为 (k) 的数组 (a),然后将 (a) 数组全排列得到 (k!)(p) 数组,要求对于任意的 (p) 数组和任意一个 (x > 0) 满足:

    [(((x mod a_1) mod a_2) ... mod a_k) = (((x mod p_1) mod p_2) ... mod p_k) ]

      特别的:(1leq a_1 < a_2 < ... < a_k)。求 (a) 数组的个数?
    (Solution:)
      要让其任意顺序的模数都相等,那么他们肯定是要满足某种规律的。我就猜测数组 (a) 一定是满足了第一项是后面所有项的因子,这个也很好证明:
      设数组 (a)(d, t_1d, t_2d, t_{k-1}d)。那么 (x) 也可以和 (d) 挂上钩,即 (x = kd + c),对于去模 (a) 数组的结果显然是 (c),对于去模 (p) 数组,遇到比 (x) 大的不会变,比 (x) 小的,那么 (x) 就会逐渐变小,但是 (c) 是始终存在的,直到遇到 (d),变为 (c),而之后的数都比 (c) 大,显然 (c) 就是结果,与模 (a) 数组的结果一致,所以是可行的。
      那么我们就可以去枚举 (d),然后算出 ([1, n])(d) 的倍数的个数,排列组合即可求解。
    (Code:)

    /*
    @Author: nonameless
    @Date:   2020-05-29 11:25:26
    @Email:  2835391726@qq.com
    @Blog:   https://www.cnblogs.com/nonameless/
    */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    const double eps = 1e-8;
    const double PI  = acos(-1.0);
    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 mod = 998244353;
    const int N = 5e5 + 10;
    
    ll f[N];
    
    ll fPow(ll a, ll b){
        ll res = 1;
        while(b){
            if(b & 1) res = res * a % mod;
            b >>= 1;
            a = a * a % mod;
        }
        return res;
    }
    
    ll C(int a, int b){
        return f[a] * fPow(f[b] * f[a - b] % mod, mod - 2);
    }
    
    int main(){
    
        int n, k;
        cin >> n >> k;
    
        f[0] = 1;
        for(int i = 1; i <= n; i ++) f[i] = f[i - 1] * i % mod;
    
        ll ans = 0;
        for(int i = 1; i <= n; i ++){
            int d = n / i - 1;
            if(d < k - 1) break;
            ans = (ans + C(d, k - 1)) % mod;
        }
    
        cout << ans << endl;
    
    
        return 0;
    }
    
    
  • 相关阅读:
    MongoDB 副本集搭建 & 副本集扩容
    MongoDB 部署 & 基础命令
    MyBatis常见面试题:#{}和${}的区别是什么?
    MyBatis常见面试题:说说MyBatis的工作原理
    Java四种引用类型回收时机介绍
    Java虚拟机之垃圾回收器
    Servlet中过滤器、监听器和拦截器的区别
    Java里一个线程两次调用start()方法会出现什么情况
    二叉树、二叉查找树、平衡树和红黑树概念及其性质
    转:基于Redis实现延时队列
  • 原文地址:https://www.cnblogs.com/nonameless/p/12988387.html
Copyright © 2020-2023  润新知