zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 95 (Rated for Div. 2) A

    题目链接


    A. Buying Torches

    思路:

    直接计算出需要的木棍,然后取除以 ((x -1))(向上取整),最后在加上 (k) 即可。

    代码:
    /*
     * @Author       : nonameless
     * @Date         : 2020-09-14 22:22:07
     * @LastEditors  : nonameless
     * @LastEditTime : 2020-09-15 02:03:23
     */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define toStr(name) (#name)
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f3f3f;
    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); }
    
    template<class T>
    inline void read(T &x){
        x = 0;
        int f = 1;
        char c = getchar();
        while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        x = x * f;
    }
    
    template<class T>
    inline void out(string a, T x){ cout << a << " = " << x << endl; }
    
    
    int main(){
    
        int t; read(t);
        while(t --){
            ll x, y, k; cin >> x >> y >> k;
            ll all = k * y + k - 1;
            ll tmp = all / (x - 1);
            if(all % (x - 1)) tmp ++;
            tmp += k;
            cout << tmp << endl;
        }
        
        return 0;
    }
    

    B. Negative Prefixes

    思路 :

    直接计算出和 (sum)

    • (sum < 0) :说明 (k = n),直接输出原数组即可。
    • (sum geq 0) :说明第 (n) 位是 (geq 0) 的,那么我们要 (n - 1) 位也尽量 (geq 0),那么就要把可变动的数里最小的放在当前位(如果当前位是可变的),依次类推,直到 (sum < 0)

    注:其实就是把可改变的数拿来排序,然后从大到小依次填充。

    代码:
    /*
     * @Author       : nonameless
     * @Date         : 2020-09-14 23:01:26
     * @LastEditors  : nonameless
     * @LastEditTime : 2020-09-15 02:10:22
     */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define toStr(name) (#name)
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f3f3f;
    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); }
    
    template<class T>
    inline void read(T &x){
        x = 0;
        int f = 1;
        char c = getchar();
        while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        x = x * f;
    }
    
    template<class T>
    inline void out(string a, T x){ cout << a << " = " << x << endl; }
    
    const int N = 110;
    
    int a[N], vis[N], b[N];
    
    int main(){
    
        int t; read(t);
        while(t --){
            int n; read(n);
            ll sum = 0;
            int cnt = 0;
            for(int i = 1; i <= n; i ++) read(a[i]);
            for(int i = 1; i <= n; i ++) read(vis[i]);
            for(int i = 1; i <= n; i ++) sum += a[i];
            for(int i = 1; i <= n; i ++) if(vis[i] == 0) b[++cnt] = a[i];
            sort(b + 1, b + cnt + 1);
            int idx = 0;
            if(sum < 0){
                for(int i = 1; i <= n; i ++) printf("%d ", a[i]);
                puts("");
            } else{
                for(int i = n; i >= 1; i --){
                    if(sum < 0) break;
                    if(vis[i] == 1){
                        sum -= a[i];
                        continue;
                    } else{
                        a[i] = b[++idx];
                        sum -= a[i];
                        vis[i] = 1;
                    }
                }
                for(int i = 1; i <= n; i ++){
                    if(vis[i] == 0) a[i] = b[++idx];
                    printf("%d ", a[i]);
                }
                puts("");
            }
        }
        return 0;
    }
    

    C. Mortal Kombat Tower

    思路:

    首先很容易想到的是:如果第一位是 (1),那么答案加一。

    那么还有什么情况是一定要跳过 (1) 的呢?考虑:(111) 这种情况,我们最多打死两个怪物,那么朋友必须要面对一只 (hard) 的怪物,所以答案加一。

    而对于其他情况:(000, 001, 010, 011, 100, 101, 110) ,我们的朋友都是可以避免 (1) 的。

    所以只要统计下 ([2, n]) 的区间内存在几个 (111) 即可,特判第一位。

    代码:
    /*
     * @Author       : nonameless
     * @Date         : 2020-09-14 23:28:28
     * @LastEditors  : nonameless
     * @LastEditTime : 2020-09-14 23:38:37
     */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define toStr(name) (#name)
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f3f3f;
    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); }
    
    template<class T>
    inline void read(T &x){
        x = 0;
        int f = 1;
        char c = getchar();
        while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        x = x * f;
    }
    
    template<class T>
    inline void out(string a, T x){ cout << a << " = " << x << endl; }
    
    const int N = 2e5 + 10;
    
    int a[N];
    
    int main(){
    
        int t; read(t);
        while(t --){
            int n; read(n);
            for(int i = 1; i <= n; i ++) read(a[i]);
            int ans = 0, cnt = 0;
            if(a[1] == 1) ans ++;
            for(int i = 2; i <= n; i ++){
                if(a[i] == 1) cnt ++;
                else cnt = 0;
                if(cnt == 3) {
                    ans ++;
                    cnt = 0;
                }
            }
            cout << ans << endl;
        }
        return 0;
    }
    
    

    D. Trash Problem

    思路:

    可以向天再借五百年就好了

    显然最后合并的两堆的距离最远。

    设:(a, b, c, d)((a:最左边的,b:合并完的某一堆,c:合并完的某一堆,d:最右边的))

    那么 (ans = b - a + d - c = d - a - (c - b))

    即最右边的减去最左边的,再减去相邻距离最远的。

    那么用两个 (set) 来维护信息,(s_1) 维护当前的所有坐标,(s_2) 维护相邻两堆的距离。

    对于每次插入或删除的数,找出其在 (s_1) 的前驱和后继,然后更新 (s_2) 即可。

    注:

    • (s_2) 必须是一个 (multiset)
    • 找前驱和后继注意处理边界
    代码:
    /*
     * @Author       : nonameless
     * @Date         : 2020-09-15 00:13:17
     * @LastEditors  : nonameless
     * @LastEditTime : 2020-09-15 01:58:19
     */
    #include <bits/stdc++.h>
    #define x first
    #define y second
    #define pb push_back
    #define sz(x) (int)x.size()
    #define toStr(name) (#name)
    #define all(x) x.begin(), x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> PLL;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const double eps = 1e-6;
    const double PI  = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const ll LNF  = 0x3f3f3f3f3f3f3f3f;
    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); }
    
    template<class T>
    inline void read(T &x){
        x = 0;
        int f = 1;
        char c = getchar();
        while(c < '0' || c > '9') if(c == '-') { f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        x = x * f;
    }
    
    template<class T>
    inline void out(string a, T x){ cout << a << " = " << x << endl; }
    
    multiset<ll> s1, s2;
    
    
    int main(){
    
        int n, q; read(n); read(q);
    
        auto add = [&](ll x){
            auto it = s1.lower_bound(x);
            if(it != s1.end()) s2.insert(*it - x);
            if(it != s1.begin()) s2.insert(x - *prev(it));
            if(it != s1.end() && it != s1.begin()) s2.erase(s2.find(*it - *prev(it)));
            s1.insert(x);
        };
    
        auto del = [&](ll x){
            s1.erase(x);
            auto it = s1.lower_bound(x);
            if(it != s1.end()) s2.erase(s2.find(*it - x));
            if(it != s1.begin()) s2.erase(s2.find(x - *prev(it)));
            if(it != s1.end() && it != s1.begin()) s2.insert(*it - *prev(it));
        };
    
        auto calc = [&]() -> ll {
            if(sz(s1) <= 2) return 0;
            return *prev(s1.end()) - *s1.begin() - *prev(s2.end());
        };
        
        for(int i = 1; i <= n; i ++){
            ll x; read(x);
            add(x);
            //printf("sz(s2) = %d
    ", sz(s2));
        }
        printf("%lld
    ", calc());
        
    
        while(q --){
            int op; read(op);
            ll x; read(x);
            if(op == 1) add(x);
            else del(x);
            printf("%lld
    ", calc());
        }
        return 0;
    
    }
    
  • 相关阅读:
    VS Code设置同步
    ASP.NET Core 发布
    CMD命令
    通过注册表为文件(夹)添加右键菜单
    win+r 以管理员身份运行
    .NET Core部署Windows服务
    .NET Core的打包到一个exe程序
    C#枚举
    C#生成Guid
    使用Visual Studio的单元测试
  • 原文地址:https://www.cnblogs.com/nonameless/p/13670586.html
Copyright © 2011-2022 走看看