zoukankan      html  css  js  c++  java
  • 牛客练习赛59

    传送门

    A.小乔和小灰灰

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/13 19:00:59
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1000 + 5;
    
    const string s = "XiaoQiao", t = "XiaoHuiHui";
    
    string ss;
    
    void run() {
        cin >> ss;
        int len = ss.length();
        int t1 = 0, t2 = 0;
        for(int i = 0; i < len; i++) {
            if(t1 < 8 && ss[i] == s[t1]) ++t1;
            if(t2 < 10 && ss[i] == t[t2]) ++t2;
        }
        if(t1 == 8 && t2 == 10) {
            cout << "Happy" << '
    ';   
        } else cout << "emm" << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    B.牛能和小镇

    排序后贪心计算即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/13 19:12:53
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A>
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n;
    ll a[N];
     
    void run() {
        cin >> n;
        for(int i = 1; i <= n; i++) {
            int x, y; cin >> x >> y;
            a[i] = 1ll * y * (x - y) * (x - y);  
        }
        sort(a + 1, a + n + 1);
        ll ans = 0;
        for(int i = 2; i <= n; i++) {
            ans += a[i] - a[i - 1];  
        }
        cout << ans << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    C.装备合成

    题意:
    牛牛有({x})件材料(a)({y})件材料(b),用(2)件材料(a)(3)件材料(b)可以合成一件装备,用(4)件材料(a)(1)件材料(b)也可以合成一件装备。牛牛想要最大化合成的装备的数量,于是牛牛找来了你帮忙。

    思路:
    显然最终答案具有单调性。
    那么二分答案(t),假设最后用第一种方法合成了(A)件装备,那么第二种方法合成了(B)件装备,那么可以列出如下式子:

    • (2A+4Bleq x,3A+Bleq y,A+B=t).

    最后可以解出(A)的范围。二分时(check)一下是否合法即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/13 19:21:23
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
    
    ll a, b;
    bool chk(ll t) {
        ll l = ceil(1.0 * (4 * t - a) / 2), r = floor(1.0 * (b - t) / 2);
        return l <= r && l <= t && r >= 0;
    }
    
    void run() {
        cin >> a >> b;
        int l = 0, r = INF, mid;
        while(l < r) {
            mid = (l + r) >> 1;
            if(chk(mid)) l = mid + 1;
            else r = mid;   
        }
        cout << l - 1 << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    D.取石子游戏

    (sg)函数有规律,直接算就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/13 20:15:51
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
    
    ll f[N];
    int t;
    
    void init() {
        ll Max = 4e18;
        f[1] = 1, f[2] = 3;
        for(int i = 3;; i++) {
            f[i] = f[i - 1] * 2;
            if(i % 2 == 0) ++f[i];
            if(f[i] >= Max) {
                t = i; break;   
            }
        }
    }
    
    void run() {
        ll n; cin >> n;
        int p = lower_bound(f + 1, f + t + 1, n) - f;
        if(p & 1) cout << "XiaoQiao" << '
    ';
        else cout << "XiaoHuiHui" << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        init();
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    E.石子搬运

    题意:
    现有(n)堆石子,每堆有(a_i)个石头。现在可以将这(n)堆石子划分为(m)堆,每堆贡献为(k_i^2)
    然后会发生(q)个事件,每个事件为(x v),即将第(x)堆石子个数变为(v)
    对于每个事件,回答最小贡献。
    (1leq nleq mleq 400,qleq 400)

    思路:
    对于每个事件我们单独计算,总体思路就是贪心,按照差值来进行贪心。
    每次选择当前贡献能减少的最大值进行操作即可。
    可以用一个优先队列来维护。shi
    时间复杂度为(O(qnlogn))
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/13 23:06:41
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 400 + 5;
    
    int n, m, q;
    int a[N];
    
    ll calc(int v, int k) {
        int r = v % k;
        int t = v / k;
        return 1ll * r * (t + 1) * (t + 1) + 1ll * (k - r) * t * t;
    }
    
    ll solve(int v, int k) {
        return calc(v, k) - calc(v, k + 1);
    }
    
    void run() {
        cin >> n >> m;
        for(int i = 1; i <= n; i++) cin >> a[i];
        cin >> q;
        while(q--) {
            int id, v; cin >> id >> v;
            a[id] = v;
            priority_queue <pair<ll, pii>> q;
            for(int i = 1; i <= n; i++) {
                q.push(pair<ll, pii>{solve(a[i], 1), MP(a[i], 1)});   
            }
            int k = m - n;
            while(k--) {
                pair <ll, pii> now = q.top(); q.pop();
                int val = now.se.fi, t = now.se.se + 1;
                q.push(pair<ll, pii>{solve(val, t), MP(val, t)});   
            }
            ll ans = 0;
            while(!q.empty()) {
                pair <ll, pii> now = q.top(); q.pop();
                int val = now.se.fi, t = now.se.se;
                ans += calc(val, t);
            }
            cout << ans << '
    ';
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    F.小松鼠吃松果

    题意:
    (m)个位置,有(n)个时刻在某些位置会生长一个价值为(v_i)的果子,每个果子只会存在一秒。
    现在你可以任意选择一个点作为起点,每一秒只能向左或者向右移动一步。问最后能得到的最大价值是多少。

    思路:
    我们按照时间进行排序,如果我们要吃至少两个果子,那么要满足的条件为:

    • (t_j-t_igeq |p_i-p_j|)

    我们将绝对值打开,有:

    • (p_igeq p_j,t_j+p_jgeq t_i+p_i);
    • (p_i<p_j,t_j-p_jgeq t_i-p_i)

    那么令(X_i=p_i+t_i,Y_i=t_i-p_i)
    那么我们按照(X_i)进行排序,问题可以转化为带权(lis)(Y_i)就是每个数的高度。我们要求最长不下降子序列的最大权值和。利用树状数组维护即可。
    注意这里我们将问题转化为了二维问题。我们推出第二个式子的前提是按照时间排序,又可以发现只要满足第二个式子,第一个式子也自然满足了。如果没注意到这一点,就是一个三维问题,就像题解那样用树套树或者(cdq)分治这些来解决。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/14 10:23:00
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
    
    int n, m;
    int a[N], b[N];
    
    struct node {
        int id, h, v;
        bool operator < (const node &A) const {
            if(id != A.id) return id < A.id;
            return h < A.h;
        }
    }info[N];
    
    struct BIT {
        ll c[N];
        int lowbit(int x) {return x & (-x);}
        void upd(int x, ll v) {
            for(; x < N; x += lowbit(x)) c[x] = max(c[x], v);
        }   
        ll query(int x) {
            ll res = 0;
            for(; x; x -= lowbit(x)) res = max(res, c[x]);
            return res;   
        }
    }bit;
    
    void run() {
        cin >> n >> m;
        for(int i = 1; i <= m; i++) cin >> a[i];
        for(int i = 1; i <= m; i++) cin >> b[i];
        for(int i = 1; i <= n; i++) {
            int t, p, c; cin >> t >> p >> c;
            int x = a[p], y = b[p] + t;
            info[i] = node{y - x, x + y, c};
        }
        sort(info + 1, info + n + 1);
        vector <int> v;
        for(int i = 1; i <= n; i++) v.push_back(info[i].h);
        sort(all(v));
        v.erase(unique(all(v)), v.end());
        for(int i = 1; i <= n; i++) {
            int h = lower_bound(all(v), info[i].h) - v.begin() + 1;
            bit.upd(h, bit.query(h) + info[i].v);
        }
        ll ans = bit.query(n);
        cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    设计模式总结
    设计模式之工厂
    C#
    UML画图总结
    UML视频总结
    类图
    读取文件信息
    HMAC算法加密
    SHA_1计算消息摘要
    获取指定长度的随机字符串
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12502592.html
Copyright © 2011-2022 走看看