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

    传送门

    A. FashionabLee

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/23 22:06:06
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #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 << std::endl; }
      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;
     
    void run() {
        int n; cin >> n;
        if (n < 4) {
            cout << "NO" << '
    ';
        } else {
            n -= 4;
            if (n % 4 == 0) cout << "YES" << '
    ';
            else cout << "NO" << '
    ';
        }
    }
     
    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;
    }
    

    B. AccurateLee

    注意到(1....0)这样的形式最后一定能变为一个(0)。那么因为要求字典序最小,所以贪心缩一下就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/23 22:09:22
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #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 << std::endl; }
      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;
     
    void run() {
        int n; cin >> n;
        string s; cin >> s;
        int fir = n, last = -1;
        for (int i = 0; i < n; i++) {
            if (s[i] == '1') {
                fir = i;
                break;
            }
        }
        for (int i = n - 1; i >= 0; i--) {
            if (s[i] == '0') {
                last = i;
                break;
            }
        }
        for (int i = 0; i < fir; i++) {
            cout << s[i];
        }
        if (fir < last) {
            cout << 0;
        }
        for (int i = last + 1; i < n; i++) {
            cout << s[i];
        }
        cout << '
    ';
    }
     
    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;
    }
    

    C. RationalLee

    贪心分配即可。
    首先最大的(k)个数一定会产生一次贡献,其次最小的那个数也一定会产生一次贡献。
    现在是要使得每组中最小值之和最大。所以按照(w_i)从大到小排序,后面较小的值能放就放,这样能使得每组最小值尽可能大。
    注意(w_i=1)的组最大值会产生两次贡献,那么直接将其钦定为尽可能大的贡献即可。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/23 22:33:03
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #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 << std::endl; }
      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;
     
    void run() {
        int n, k; cin >> n >> k;
        vector <int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        vector <int> w(k);
        for (int i = 0; i < k; i++) {
            cin >> w[i];
        }
        vector <int> p(n), p2(k);
        iota(all(p), 0);
        iota(all(p2), 0);
        sort(all(p), [&](int i, int j) {return a[i] > a[j];});
        sort(all(p2), [&](int i, int j) {return w[i] > w[j];});
        ll ans = 0;
        for (int i = 0; i < k; i++) {
            ans += a[p[i]];
        }
        int t = n - 1, l = 0;
        for (int i = 0; i < k; i++) {
            if (w[p2[i]] > 1) {
                --w[p2[i]];
                ans += a[p[t]];
                t -= w[p2[i]];
            } else {
                ans += a[p[l++]];
            }
        }
        cout << ans << '
    ';
    }
     
    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. TediousLee

    题意:
    定义一个类似于树一样的东西,一开始有一个结点,之后每一时刻将发生以下变化:

    • 若一个结点没有儿子,则增加一个儿子;
    • 若一个结点有一个儿子,则增加两个儿子;
    • 若一个结点有超过两个儿子,则不变。

    类似于下图:

    依次为(t=1,2,3)的情况。

    现在要给尽可能多的点染色,要求一定是如下这样:

    并且还没被染过色。
    输出最大染色点数。

    思路:
    基本思想还是贪心,染色肯定自下往上染最优。
    考虑图像的变化情况,对于(n)时刻,我们记其答案为(f(n)),那么其中间那个儿子的状态为(n-1)时刻,两边的儿子状态为(n-2)时刻。所以很容易得到转移式子:

    • (f(n)=f(n-1)+2cdot f(n-2))

    注意我们还可能将当前根节点染色,前提是其三个儿子都没染色,所以用一个(g)转移一下是否能染色就行。
    其实也不用转移,如果(n\%3)当前一定能够染色。
    详见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/23 22:59:16
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #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 << std::endl; }
      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 = 2e6 + 5, MOD = 1e9 + 7;
     
    int f[N], g[N];
     
    void init() {
        f[3] = f[4] = 1;
        g[3] = 1;
        for (int i = 5; i < N; i++) {
            g[i] = (g[i - 2] + g[i - 1] == 0);
            f[i] = ((2ll * f[i - 2] % MOD + f[i - 1]) % MOD + g[i]) % MOD;
        }
    }
     
    void run() {
        int n; cin >> n;
        int ans = 4ll * f[n] % MOD;
        cout << ans << '
    ';
    }
     
    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. DeadLee

    题意:
    (n)种食物(m)个朋友,每个朋友有两种最喜欢吃的食物。
    现在你每次邀请一个朋友来吃饭,这个朋友只会吃最喜欢的食物,现在每种食物有(w_i)份。每次每个朋友都会吃最多两份不同的最喜欢的食物。如果当前没有最喜欢的食物的话,那么就会吃了你。
    现在问如何安排顺序,使得你能够活下来。

    思路:
    注意这个题是每个朋友最多吃两份不同的最喜欢食物,也就是如果一个人喜欢(x_i,y_i)并且刚好都有库存,那么就会各吃一份。
    这个题很容易想到建图,对于一个朋友,我们连无向边((x_i,y_i))。现在每次邀请一位朋友就会去掉一条无向边。现在已有每个点的度数(d_i)以及容量(w_i)
    注意到若某个点(d_ileq w_i),那么这个菜无论怎么吃都不会吃不够,也就是对应的边都可以随意删。因为这些朋友是永远不会吃人的,所以直觉上我们将其越留在后面越棒。
    因此就有了思路:从后往前贪心处理,对于某个点满足(d_ileq w_i),我们枚举每条边进行删除,并且减少其它点的(d_j),代表现在这个食物少了一个人喜欢,也就是说让前面的人更多选择这个食物,并且尽可能吃够,而枚举的人就只吃(i)这种食物。
    如果最后还剩下边没有删除就是不合法的情况。
    很有意思的一个贪心!

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/24 8:45:45
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #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 << std::endl; }
      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;
     
    void run() {
        int n, m; cin >> n >> m;
        vector <int> d(n), w(n);
        for (int i = 0; i < n; i++) {
            cin >> w[i];
        }
        vector <vector <pii>> G(n);
        for (int i = 0; i < m; i++) {
            int u, v; cin >> u >> v;
            --u, -- v;
            G[u].push_back(MP(v, i));
            G[v].push_back(MP(u, i));
            ++d[u], ++d[v];
        }
        queue <int> q;
        for (int i = 0; i < n; i++) {
            if (w[i] >= d[i]) {
                q.push(i);
            }
        }
        vector <int> ans;
        vector <bool> check(m);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (auto it : G[u]) {
                int v = it.fi, id = it.se;
                if (check[id]) continue;
                check[id] = true;
                ans.push_back(id);
                if (--d[v] == w[v]) {
                    q.push(v);
                }
            }
        }
        if (sz(ans) < m) {
            cout << "DEAD" << '
    ';
        } else {
            cout << "ALIVE" << '
    ';
            reverse(all(ans));
            for (auto it : ans) {
                cout << it + 1 << ' ';
            }
            cout << '
    ';
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    F. BareLee

    题意:
    现有(t)回合,每一回合有两个数(s_i,e_i)。在每一轮游戏中,两个人轮流选择一个数(a)(一开始为(s_i)),将其变为(2a,a+1),如果(a>e_i)那么这轮游戏这个人就失败。
    现在规定最后一轮赢的玩家获得整场比赛的胜利,问先手是否能赢得比赛或者先手是否能输掉比赛。注意你的对手是很聪明的,肯定不想让你轻易达到目标。

    思路:
    首先我们看一轮游戏中是否必胜或者必败,这涉及到分情况考虑:
    我们用(f[i][j])表示状态为(i,j)时是否必胜,(g[i][j])同理表示必败。其中(i)(a)(j)(e)
    必胜:

    • 如果(j)为奇数,那么(i)为奇数则必败,否则必胜;
    • 如果(j)为偶数,那么:
      • (i>j/2)(i)为偶数则必败,否则必胜;
      • (i>j/4),则必胜;
      • 否则问题转化为了(f[i][j/4])

    必败:

    • 如果(i>j/2),显然可以直接输掉;
    • 否则问题转化为了(f[i][j/2])

    那么求出每一轮的状态(f[s_i][e_i],g[s_i][e_i])过后,考虑如何求出整轮游戏的状态。
    我们用(f)表示能否先手,(s)表示能否后手,显然初始状态为(f=1,g=0)
    之后枚举每一轮,若某轮开始时(f=s),比如(f=s=1),也就是先手可以选择先手还是后手,那么之后的游戏显然他是必胜的,因为如果后面有必胜态他就必胜,否则就把问题抛给对面,这样他也是必胜。
    否则就根据本轮的情况更新(f,s),因为现在(f ot ={s}),假设(f=1),那么显然如果有一个必败态就能继续先手,如果有一个必胜态就能后手。其余情况同理。
    最后输出(s f)即可,注意顺序要反一下。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/24 15:08:23
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #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 << std::endl; }
      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 Win(ll s, ll e) {
        if (e & 1) {
            if (s & 1) return 0;
            return 1;
        }
        if (s > e / 2) {
            if (s & 1) return 1;
            return 0;
        }
        if (s > e / 4) {
            return 1;
        }
        return Win(s, e / 4);
    }
     
    int Lose(ll s, ll e) {
        if (s > e / 2) {
            return 1;
        }
        return Win(s, e / 2);
    }
     
    void run() {
        int n; cin >> n;
        vector <pii> r(n);
        for (int i = 0; i < n; i++) {
            ll s, e; cin >> s >> e;
            r[i] = MP(Win(s, e), Lose(s, e));
        }
        int f = 1, s = 0;
        for (int i = 0; i < n; i++) {
            if (f == s) break;
            r[i].fi ^= s;
            r[i].se ^= s;
            f = r[i].se;
            s = r[i].fi;
        }
        cout << s << ' ' << f << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    php使用 _before_index() 来实现访问页面前,判断登录
    php使用 _before_index() 来实现访问页面前,判断登录
    查询方式实例演示
    查询方式实例演示
    haproxy timeout server 46000 后台超时时间
    haproxy timeout server 46000 后台超时时间
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/13188281.html
Copyright © 2011-2022 走看看