zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 45 Editorial

    A. Commentary Boxes

    #include<bits/stdc++.h>
    #define mem(arry, in) memset(arry, in, sizeof(arry))
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    
    int main()
    {
        ll n, m, a, b;
        cin >> n >> m >> a >> b;
        n = n % m;
        ll res1 = (m - n) * a;
        ll res2 = n * b;
        cout << min(res1, res2) << endl;
    }

    B. Micro-World

    题解:从小到大枚举,观察是否能被前一个(  i + 1 )数消掉。注意相同的数。

    #include<bits/stdc++.h>
    #define mem(arry, in) memset(arry, in, sizeof(arry))
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    
    const int maxn = 200005;
    
    int n, K;
    int a[maxn], use[maxn * 10];
    int main() { cin >> n >> K; for(int i = 1; i <= n; i++){ int tp; cin >> tp; use[tp]++; } int m = 0; for(int i = 1; i <= 1000000; i++) if(use[i]) a[++m] = i; //for(int i = 1; i <= m; i++) cout << a[i] << " "; //cout << endl; int tp = a[1]; int cnt = 0; for(int i = 2; i <= m; i++){ if(a[i] <= tp + K) cnt += use[tp]; tp = a[i]; } cout << n - cnt << endl; return 0; }

    C. Bracket Sequences Concatenation Problem

    题解:能匹配的情况分别统计一下,比如"(" 和 ")","((" 和 "))",、、、、

    #include<bits/stdc++.h>
    #define mem(arry, in) memset(arry, in, sizeof(arry))
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    
    const int maxn = 300005;
    
    int n, cnt, m;
    int a[maxn], b[maxn];
    
    stack<char> q;
    
    int main()
    {
        while(!q.empty()) q.pop();
    
        cin >> n;
        cnt = 0;
        for(int i = 0; i < n; i++){
            char s[maxn];
            scanf("%s", s);
            m = strlen(s);
    
            q.push(s[0]);
            for(int j = 1; j < m; j++){
                if(q.empty()) q.push(s[j]);
                else{
                    if(s[j] == ')'){
                        if(q.top() == '(') q.pop();
                        else q.push(s[j]);
                    }
                    else q.push(s[j]);
                }
            }
    
            if(q.empty()) cnt++;
            else{
                int g = 0, t = 0;
                while(!q.empty()){
                    if(q.top() == '(') g++;
                    else t++;
                    q.pop();
                }
                if(g && !t) a[g]++;
                if(!g && t) b[t]++;
            }
        }
    
        ll res = (ll)cnt * (ll)cnt;
        for(int i = 0; i <= maxn; i++) if(a[i] && b[i]) res += (ll)a[i] * (ll)b[i];
        cout << res << endl;
        return 0;
    }

     E. Post Lamps

    没理解到题意,看代码貌似灯的照亮范围只能选1~k中的一种,所以可以直接暴力求解。n(1 + 1/2 + 1/3 + 1/4 + 1/5 + ·····+ 1/n) = nlog(n)

    如果灯的亮度可以在1~k中任意选,感觉会是个背包或者区间DP

    #include<bits/stdc++.h>
    #define ll long long
    #define P pair<int,int>
    #define maxn (int)1e6 + 7
    #define INF (unsigned long long int)1e18
    #define mem(arry, in) memset(arry, in, sizeof(arry))
    using namespace std;
    
    int n, m, k;
    int use[maxn], a[maxn], s[maxn];
    
    int main()
    {
        int tp, l = 0;
    
        cin >> n >> m >> k;
        for(int i = 1; i <= m; i++) scanf("%d", &tp), use[tp] = 1;
        for(int i = 1; i <= k; i++) scanf("%d", &a[i]);
    
        if(use[0]) { cout << -1 << endl; return 0; }
    
        for(int i = 1; i < n; i++){
            if(use[i]) s[i] = s[i - 1] + 1;
            else s[i] = 0;
            l = max(l, s[i]);
        }
    
        ll res = INF;
        for(int i = l + 1; i <= k; i++){
            int cnt = 0;
            for(int j = 0; j < n; j += i){
                if(use[j]) j -= s[j];
                cnt++;
            }
            res = min(res, (ll)cnt * (ll)a[i]);
        }
    
        cout << (res == INF ? -1 : res) << endl;
        return 0;
    }

    F. Flow Control 

    题解:如果sigma(a[i])!=0,那么一定不能构造出来。一条边的端点假设是 u, v,对u来说是进流(出流)的边,对v来说必定是出流(进流)的边,所以在 a1 + a2 + a3 + ······ + am 这个式子中,这条边必定出现两次,且互为相反数,故sigma(a[i])=0。对一个点来说只考虑进流和出流的情况,所以构造一颗生成树,树的叶子要么是进流,要么是出流,自底向上计算。

    实现的话DFS,不一定用并查集。记录方向也是小技巧。

    #pragma warning(disable:4996)
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define P pair<int,int>
    #define maxn (int)2e5 + 7
    #define INF (unsigned long long int)1e18
    #define mem(arry, in) memset(arry, in, sizeof(arry))
    using namespace std;
    
    int n, m;
    int a[maxn], use[maxn], ans[maxn];
    
    vector<P> g[maxn];
    
    void DFS(int u) {
        use[u] = 1;
        for (auto x : g[u]) {
            int v = x.first;
            if (use[v]) continue;
            DFS(v);
            ans[abs(x.second)] = (x.second > 0 ? a[v] : -a[v]);
            a[u] += a[v];
        }
    }
    
    int main()
    {
        int res = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]), res += a[i];
        scanf("%d", &m);
        for (int i = 1; i <= m; i++) {
            int u, v;
            scanf("%d %d", &u, &v);
            g[u].push_back(P(v, i));
            g[v].push_back(P(u, -i));
        }
        if (res) {
            puts("Impossible");
        }
        else {
            puts("Possible");
            DFS(1);
            for (int i = 1; i <= m; i++) printf("%d
    ", ans[i]);
        }
        return 0;
    }

    G. GCD Counting

    注意单独的一个点也可以称为一条路径。

    超级暴力的做法,以1为根的树,暴力的从叶子向根记录所有路径的gcd值。有小于1s的做法,得去学习一下

    vector<int> e[maxn];
    map<int, ll> mp[maxn];
    
    int n, a[maxn];
    ll cnt[maxn];
    
    int gcd(int a,int b) { return !b ? a : gcd(b, a % b); }
    
    void DFS(int u, int p){
        mp[u][a[u]]++;
        for(int v : e[u]){
            if(v == p) continue;
            DFS(v, u);
            map<int, ll> :: iterator itu, itv;
            for(itu = mp[u].begin(); itu != mp[u].end(); itu++){
                for(itv = mp[v].begin(); itv != mp[v].end(); itv++){
                    cnt[gcd(itu->first, itv->first)] += (itu->second * itv->second);
                }
            }
    //存子树的gcd值!!!!
    for(itv = mp[v].begin(); itv != mp[v].end(); itv++){ mp[u][gcd(a[u], itv->first)] += itv->second; } mp[v].clear(); } }
  • 相关阅读:
    Install Java on Ubuntu server
    Java 空引用访问静态不会发生空指针异常
    Java 什么时候使用static
    Java 空指针异常
    java 方法的返回值
    python中直接复制,浅拷贝,深拷贝
    python 操作ppt转换为pdf
    数组排序
    qooxdoo框架环境搭建
    python 链表实现 双向链表和单向循环链表
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9172891.html
Copyright © 2011-2022 走看看