• AcWing第6场周赛题解


    A. AcWing 3733. 去掉一个元素

    题目链接:https://www.acwing.com/problem/content/3736/

    题目大意:问共有多少个元素满足,在去掉该元素后,剩余元素的相加之和为一个偶数(注意,0 也算偶数)。

    解题思路:若和为奇数,答案为奇数个数;若和为偶数,答案为偶数个数。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    
    int n, a, sum, cnt;
    
    int main() {
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> a;
            sum += a;
            if (a % 2) cnt++;
        }
        if (sum%2) cout << cnt << endl;
        else cout << n - cnt << endl;
        return 0;
    }
    

    B. AcWing 3734. 求和

    题目链接:https://www.acwing.com/problem/content/3737/

    题目大意:按照题目描述求区间内所有数字的和。

    解题思路:定义只包含 4 或 7 的数位 Lucky number,则我们其实可以直接由当前的数跳转到下一个 Lucky number,然后批量求和。Lucky number 其实没有多少,所以可以基于这样的思路进行模拟。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    
    long long nxt(long long a) {
        long long t = 1, b = 0;
        while (a) {
            if (a % 10 == 4) {
                return (a + 3) * t + b;
            }
            b = b * 10 + 4;
            a /= 10;
            t *= 10;
        }
        return b * 10 + 4;
    }
    
    long long l, r, sum;
    
    int main() {
        cin >> l >> r;
        for (long long a = 4; l <= r; a = nxt(a)) {
            if (a >= l) {
                long long p = min(a, r);
                sum += (p - l + 1) * a;
                l = p + 1;
            }
        }
        cout << sum << endl;
        return 0;
    }
    

    C. AcWing 3735. 构造完全图

    题目链接:https://www.acwing.com/problem/content/3738/

    题目大意:每次操作时,可以选择其中一个点,找到所有和它直接相连的点,使这些点两两之间连边(若两点之间已经存在边,则无需重复连接)。问,至少多少次操作以后,可以将整个图变为一个完全图?

    解题思路:状压dp,基于一个贪心思想,思想来自于 题解视频 ,但是贪心思想的证明没有完全搞明白。每次选择一个点,则所有与这个点邻接的点都会加入这个点所在的极大连通子图,形成一个更大的极大连通子图。由于数据量比较小所以可以状态压缩。

    示例程序参考了 我已经不想再做刺客了大佬的代码

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    int f[1<<22], n, m, b[22];
    pair<int, int> step[1<<22]; // {前一个状态, 选择的点}
    
    int main() {
        cin >> n >> m;
        if (m == n*(n-1)/2) {   // 本身就是一个团
            cout << 0 << endl;
            return 0;
        }
        while (m--) {
            int u, v;
            cin >> u >> v;
            u--, v--;
            b[u] |= (1<<v);
            b[v] |= (1<<u);
        }
        memset(f, 0x3f, sizeof(f));
        for (int i = 0; i < n; i++) {
            b[i] |= (1<<i);
            f[b[i]] = 1;
            step[b[i]] = {0, i};
        }
        for (int st = 0; st < (1<<n); st++) {
            if (f[st] == 0x3f3f3f3f) continue;
            for (int i = 0; i < n; i++) {
                if (st & (1<<i)) {
                    int st2 = st | b[i];
                    if (f[st2] > f[st] + 1) {
                        f[st2] = f[st] + 1;
                        step[st2] = {st, i};
                    }
                }
            }
        }
        int p = (1<<n) - 1;
        cout << f[p] << endl;
        while (p) {
            cout << step[p].second + 1 << " ";
            p = step[p].first;
        }
        return 0;
    }
    
  • 相关阅读:
    Java判断一个实体类对象实例的所有成员变量是否为空
    正则表达式 整数
    将定时任务cron 解析成中文
    如何使用html定义一个红色小圆点
    Oracle获取当前日期前一个月的全部日期
    京东系统架构师如何让笨重的架构变得灵巧
    POI使用详解
    Java Excel 列号数字与字母互相转换
    使用exe4j将java项目打成exe执行程序
    Address already in use: JVM_Bind错误的解决
  • 原文地址:https://www.cnblogs.com/quanjun/p/16115223.html
Copyright © 2020-2023  润新知