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;
    }
    
  • 相关阅读:
    【Android UI设计与开发】第03期:引导界面(三)仿微信引导界面以及动画效果
    【Android UI设计与开发】第02期:引导界面(二)使用ViewPager实现欢迎引导页面
    【Android UI设计与开发】第01期:引导界面(一)ViewPager介绍和使用详解
    【Android UI设计与开发】第15期:顶部标题栏(六)实现悬浮式顶部和底部标题栏效果
    Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图
    Android 百度地图开发(二)--- 定位功能之MyLocationOverlay,PopupOverlay的使用
    jsp生命周期,和知识点添加
    jsp 脚本,声明,用户端不可见注释
    初学jsp,1、配置myeclipse
    呃呃,才意识到
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/13188281.html
Copyright © 2011-2022 走看看