• Codeforces Round #646 (Div. 2) ABCDE


    A

    我人傻了, 没理解清题意

    设有x个奇数, y个偶数

    且两个奇数等于一个偶数

    所以就让偶数和成对的奇数去凑(m - 1), 并保证剩下一个奇数 则YES

    我真就sb, 忘了用奇数凑偶数的时候是凑出的成对的, 罚时全是A贡献 淦

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int N = 1e5 + 5;
     
    int n, m, _, k;
    int a[N];
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> n >> m;
            int x = 0, y = 0;
            rep (i, 1, n) 
            {
                cin >> a[i];
                if (a[i] & 1) ++x;
                else ++y;
            }
     
            m -= y;
            if (m <= 1 && x) { cout << "YES
    "; continue; }
            
            if (m % 2 == 0 && y) ++m; 
     
            if (m % 2 == 1 && (x - 1) / 2 * 2 >= m - 1 && x > 1) cout << "YES
    ";
            else cout << "NO
    ";
        }
        return 0;
    }
    

    B

    最后无非是 全零, 全一, (零)(一), (一)(零)

    你就正反求出 到i 使得1 ~ i (i ~ n) 全为零(一)的花费, 拼接一下就行

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int N = 1e3 + 5;
     
    int n, m, _, k;
    int f[2][N];
    char s[N];
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> s + 1;
            int len = 1, x = 0, y = 0;
            for (int& i = len; s[len]; ++len)
            {
                if (s[i] == '1')
                {
                    f[0][i] = f[0][i - 1];
                    f[1][i] = f[1][i - 1] + 1;
                    ++y;
                }
                else 
                {
                    f[0][i] = f[0][i - 1] + 1;
                    f[1][i] = f[1][i - 1];
                    ++x;
                }
            }
            --len;
            int ans = min(x, y);
            x = 0, y = 0;
            per (i, len, 1)
            {
                if (s[i] == '1') ++y;
                else ++x;
                ans = min(ans, f[1][i - 1] + x);
                ans = min(ans, f[0][i - 1] + y);
            }
            cout << ans << '
    ';
        }
        return 0;
    }
    

    C

    博弈

    如果X入度小于等于1, 直接赢

    否则就轮流挑其他点, 让对手将X的入度变为小于1, 就变成了奇偶判断

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int N = 1e3 + 5;
     
    int n, m, _, k;
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> n >> m;
            int cnt = 0;
            rep (i, 2, n)
            {
                int u, v; cin >> u >> v;
                if (u == m) ++cnt;
                else if (v == m) ++cnt;
            }
     
            if (cnt <= 1) cout << "Ayush
    ";
            else if (n & 1)  cout << "Ashish
    ";
            else cout << "Ayush
    ";
        }
        return 0;
    }
    

    D

    交互题, 我是吐了, 读题看了最少20min, 没时间写了

    这道题是后面补的(读题是真恶心)

    那我简单解释一下

    有个序列 a[n], 每位在 1~n 之间(可重复)
    
    有把锁, k个密码位, 每个密码位ans[i] 给你个集合 s[i]
    
    保证集合中的所有数字属于 a[n]
    
    且每对 (i != j) s[i] ∩ s[j] = 空集
    
    每个密码位 ans[i] 是 idx(idx ∈ (1 ~ n), 下表嘛) 不属于 s[i],  使得 a[idx] 最大  
    

    看懂题就很简单了, 假如 a[idx] 是 a[n] 的最大值

    最多有一个 s[i] 有 idx, (每对 s[j] 交集为空集)

    说白了除了这个s[i], 其他 ans[j] = a[idx],

    对于这个 s[i], 你在问一遍就好

    至于找 a[n] 最大值和其位置, 二分就行, 这就是为啥 最多问 12 次

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
    
    const int N = 1e3 + 5;
    
    int n, m, _, k;
    int ans[N], v[N];
    VI s[N];
    
    int main()
    {
        //ios::sync_with_stdio(0); cin.tie(0);
        for (cin >> _; _; --_)
        {
            cin >> n >> k;
            memset(v, 0, sizeof v);
            rep (i, 1, k)
            {
                int c; cin >> c;
                VI(c).swap(s[i]);
                for (int& j : s[i]) cin >> j; 
            }
    
            int mx;
            cout << '?' << ' ' << n;
            rep (i, 1, n) cout << ' ' << i;
            cout << '
    ' << endl;  cin >> mx;
    
            int l = 1, r = n;
            while (l < r)
            {
                int mid = (l + r) >> 1, res;
                cout << '?' << ' ' << (mid - l + 1);
                rep (i, l, mid) cout << ' ' << i;
                cout << '
    ' << endl; cin >> res;
                if (res == mx) r = mid;
                else l = mid + 1;
            }
    
            rep (i, 1, k)
            {
                if (!count(all(s[i]), r)) { ans[i] = mx; continue; }
                for (int j : s[i]) v[j] = 1;
                cout << '?' << ' ' << n - s[i].size();
                rep (j, 1, n) if (v[j] == 0) cout << ' ' << j;
                cout << '
    ' << endl;
                cin >> ans[i];
            }
    
            cout << '!';
            rep (i, 1, k) cout << ' ' << ans[i];
            cout << endl;
            string ss; cin >> ss;
            assert(ss == "Correct");
        }
        return 0;
    }
    

    E

    dfs

    首先, 要认识到, 孩子自己调, 和父亲调, 结果是一样的(花费不同)

    所以dfs遍历子节点, 并 a[u] = min(a[u], a[fa]), 就变成了子树能调节多少就多少, 反正花费最少

    然后字数调不了, 就是0多1少(1多0少), 让父亲去调把

    最后特判是不是 -1 就行

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef double db;
     
    const int N = 2e5 + 5;
     
    int n, m, _, k;
    int h[N], ne[N << 1], to[N << 1], tot;
    int a[N], b[N], c[N];
    int p[N], q[N];
     
    void add(int u, int v)
    {
        ne[++tot] = h[u]; h[u] = tot; to[tot] = v;
    }
     
    ll dfs(int u, int fa)
    {
        ll co = 0;
        if (a[u] > a[fa]) a[u] = a[fa];
     
        if (b[u] != c[u])
            if (c[u]) ++q[u];
            else ++p[u];
     
        for (int i = h[u]; i; i = ne[i])
        {
            int y = to[i];
            if (y == fa) continue;
            co += dfs(y, u);
            //cout << ' ' << y << ' ' << p[y] << ' ' << q[y] << '
    ';
            q[u] += q[y]; p[u] += p[y];
             //cout << '!' << u << ' ' << p[u] << ' ' << q[u] << '
    ';
        }
     
        int s = min(q[u], p[u]);
        co += 2ll * s * a[u];
        q[u] -= s, p[u] -= s;
     
        //cout << u << ' ' << co << ' ' << q[u] << ' ' << p[u] << '
    ';
        if (fa == 0 && (q[u] || p[u])) return -1;
     
        return co;
    }
     
    int main()
    {
        ios::sync_with_stdio(0); cin.tie(0);
        cin >> n; a[0] = 2e9;
        rep (i, 1, n) cin >> a[i] >> b[i] >> c[i];
     
        rep (i, 1, n - 1) 
        {
            int u, v; cin >> u >> v;
            add(u, v); add(v, u);
        }
     
        cout << dfs(1, 0);
        return 0;
    }
    
  • 相关阅读:
    锤子科技官网:问题整理及注意事项
    springboot中文文档
    Spring Framework 开发参考手册中文(在线HTML)
    .is() 全选复选的判断
    c:forEach用法
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    火狐浏览器下载文件保存文件名的乱码问题
    多线程安全的解决方法
    MySQL的concat以及group_concat的用法
    mysql 将时间转换成时间戳
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13022784.html
Copyright © 2020-2023  润新知