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

    传送门

    A. Erasing Zeroes

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/2/12 22:35:56
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #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...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 100 + 5;
     
    int n;
    char s[N];
    int pre[N];
     
    void run(){
        cin >> (s + 1);
        n = strlen(s + 1);
        for(int i = 1; i <= n; i++) pre[i] = pre[i - 1] + (s[i] == '0');
        int first = -1, end = -1;
        for(int i = 1; i <= n; i++) if(s[i] == '1') {
            if(first == -1) first = i;
            end = i;   
        }
        if(first == -1) {
            cout << 0 << '
    ';
            return;   
        }
        cout << pre[end] - pre[first - 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;
    }
    

    B. National Project

    贪心即可。
    因为至少要保证一半以上为高质量的公路,所以先计算出至少需要多少天。
    然后在此基础上分情况考虑就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/2/12 22:41:34
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #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...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n, g, b;
     
    void run(){
        cin >> n >> g >> b;
        int need = (n + 1) / 2;
        int t = (need + g - 1) / g;
        ll tot = 1ll * (t - 1) * (g + b);
        ll r = need - 1ll * g * (t - 1);
        if(tot + r >= (ll)n) {
            cout << tot + r << '
    ';
        } else cout << n << '
    ';
    }
     
    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. Perfect Keyboard

    题意:
    给出(s)串,(|s|leq 200)
    现在构造一个由(26)个小写字母组成的(t)串,要求对于任意两个在(s)串中相邻的字符,在(t)串中都相邻。
    如果不能构造则输出NO。

    思路:
    我们将相邻关系转化为图上面的连边关系,那么如果存在合法的答案,最终的图一定是由若干条链构成(单个点也视为一条链),即不存在一条环。
    那么用邻接矩阵表示出图上面的关系然后直接(dfs)即可。
    实现的时候有点细节,比如要通过删边避免重复走误判环,还要从度数为(1)的点开始搜等等。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/2/12 22:54:42
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #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...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 200 + 5;
     
    int n, tot;
    char s[N], ans[26];
    bool mp[26][26], chk[26];
     
    bool dfs(int u) {
        chk[u] = true;
        ans[++tot] = 'a' + u;
        for(int i = 0; i < 26; i++) if(mp[u][i]) {
            if(chk[i]) return false;
            mp[u][i] = mp[i][u] = 0;
            if(!dfs(i)) return false;   
            mp[u][i] = mp[i][i] = 1;
        }
        return true;
    }
     
    void run(){
        memset(chk, 0, sizeof(chk));
        memset(mp, 0, sizeof(mp));
        tot = 0;
        cin >> (s + 1);
        n = strlen(s + 1);
        for(int i = 2; i <= n; i++) {
            mp[s[i] - 'a'][s[i - 1] - 'a'] = mp[s[i - 1] - 'a'][s[i] - 'a'] = 1;
        }
        for(int i = 0; i < 26; i++) {
            int t = 0;
            for(int j = 0; j < 26; j++) {
                if(mp[i][j]) ++t;
            }   
            if(t == 1) {
                if(!chk[i] && !dfs(i)) {
                    cout << "NO" << '
    ';
                    return;
                }   
            }
            if(t > 2) {
                cout << "NO" << '
    ';
                return;   
            }
        }
        for(int i = 0; i < 26; i++) {
            if(!chk[i] && !dfs(i)) {
                cout << "NO" << '
    ';
                return;
            }
        }
        cout << "YES" << '
    ';
        for(int i = 1; i <= tot; i++) cout << ans[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;
    }
    

    D. Fill The Bag

    题意:
    现有一背包,容量为(n,nleq 10^{18}),有(m)个物品,每个物品占用容量为(a_i,1leq a_ileq 10^9),保证对于每个(a_i),都存在一个非负整数(x),使得(2^x=a_i)
    现在可以执行任意次如下操作:将(a_i)划分为两个(frac{a_i}{2})
    现在要用最少的划分次数,来填满这个背包。

    思路:
    显然可以发现,如果对(n)进行二进制分解,那么我们只需要保证对应二进制位上面为(1)即可。
    所以贪心策略为:对于某一位而言,肯定能用前面的来堆就用前面的,否则就把后面最近的一个分解,使得这一位为(1)
    实现时我们从低位到高位考虑,某一位考虑完过后,这一位剩下的显然堆在后面最优。如果从高位往低位考虑,则贪心起来十分困难。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/2/12 23:21:06
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #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...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int a[N];
    int cnt[64];
     
    void run(){ 
        for(int i = 0; i < 64; i++) cnt[i] = 0;
        ll n; int m;
        cin >> n >> m;
        ll sum = 0;
        for(int i = 1; i <= m; i++) {
            cin >> a[i]; sum += a[i];
            int x = a[i] / 2, t = 0;
            while(x) t++, x /= 2; 
            ++cnt[t];
        }
        if(sum < n) {
            cout << -1 << '
    ';
            return;   
        }
        int ans = 0;
        for(int i = 0; i < 64; i++) {
            bool need = false;
            if(n >> i & 1) need = true;
            if(cnt[i] == 0 && need) {
                for(int j = i + 1; j < 64; j++) {
                    if(cnt[j] >= 1) {
                        ans += j - i;
                        for(int k = i; k < j; k++) ++cnt[k];
                        ++cnt[i], --cnt[j];
                        break;
                    } 
                }
            }
            if(need) --cnt[i];
            cnt[i + 1] += cnt[i] / 2;
        }
        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;
    }
    

    E. Erase Subsequences

    题意:
    给出一个字符串,现在可以执行如下操作不超过两次:

    • 选择任意一个(s)串的子序列,然后将其从(s)中移除,拼接在(t)串后面(初始(t)串为空)。

    现在给出(s)串和(t)串,回答是否能从(s)串得到(t)串。

    思路:
    可以考虑枚举(t)串分隔位置,那么现在就相当于要从(s)串中选出两个不相交的子序列分别为(t_1,t_2)
    最直接的实现是一个(O(n^3))(dp:dp_{i,j,k})表示现在位于(s)串的第(i)位,位于(t_1)的第(j)位,(t_2)的第(k)位,转移的时候直接枚举合法状态进行转移。总的时间复杂度为(O(n^4))
    现在我们对这个(dp)进行优化。
    注意到我们其实并不需要关注(s)串匹配在了哪个位置,只要当(t_1,t_2)匹配完时,(s)串的指针不超过末尾字符即可。
    那么定义(dp_{i,j}:t_1)匹配到了(i,t_2)匹配到了(j),此时需要(s)的最短长度为多少。那么转移的时候直接(O(n^2))枚举即可。
    所以总的时间复杂度为(O(n^3))

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/2/13 9:56:57
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #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...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 400 + 5;
     
    int n, m;
    char s[N], t[N];
    int nxt[N][26];
    int dp[N][N];
     
    int solve(char *s, int n, char *t, int m) {
        memset(dp, INF, sizeof(dp));
        dp[0][0] = 0;
        for(int i = 0; i <= n; i++) {
            for(int j = 0; j <= m; j++) {
                if(i) dp[i][j] = min(dp[i][j], nxt[dp[i - 1][j]][s[i] - 'a']);
                if(j) dp[i][j] = min(dp[i][j], nxt[dp[i][j - 1]][t[j] - 'a']);
            }
        }
        return dp[n][m];
    }
     
    void run(){
        cin >> (s + 1) >> (t + 1);
        n = strlen(s + 1);
        m = strlen(t + 1);
        memset(nxt, 0, sizeof(nxt));
        for(int i = 0; i < 26; i++) nxt[n + 1][i] = n + 1;
        for(int i = n; i >= 0; i--) {
            for(int j = 0; j < 26; j++) {
                if(s[i + 1] == 'a' + j) nxt[i][j] = i + 1;
                else nxt[i][j] = nxt[i + 1][j];
            }
        }
        int ans = INF;
        for(int i = 1; i <= m; i++) {
            ans = min(ans, solve(t, i, t + i, m - i));
        }
        if(ans <= n) 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;
    }
    
  • 相关阅读:
    ZOJ4134 Unrooted Trie(dfs序+线段树)
    ZOJ4127 Grid with Arrows(欧拉路径的判断)
    CF1037E Trips(思维)
    django学习第十四天--Forms和ModelForm
    django学习第十三天--自定义中间件
    图书管理系统---基于ajax删除数据
    django学习第十二天--ajax请求和csrftoken认证的三种方式
    django中修改QueryDict数据类型和转成普通字典
    图书管理系统进阶---多表操作
    locals()用法
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12303764.html
Copyright © 2011-2022 走看看