AtCoder Beginner Contest 321

这篇具有很好参考价值的文章主要介绍了AtCoder Beginner Contest 321。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

A - 321-like Checker (abc321 A)

题目大意

给定一个数,问从高位到低位,数字是不是递减的。

解题思路

可以以字符串读入,然后依次判断即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    string s;
    cin >> s;
    auto ok = [&]() {
        for (int i = 0; i < s.size() - 1; ++i) {
            if (s[i + 1] >= s[i])
                return false;
        }
        return true;
    };
    if (ok())
        cout << "Yes" << '\n';
    else
        cout << "No" << '\n';

    return 0;
}



B - Cutoff (abc321 B)

题目大意

给定\(n-1\)个数字,问最后一个数字最少是多少,使得你的分数不小于 \(x\)

数字在 \([0,100]\)之间。分数是去掉最低最高后的和。

解题思路

因为范围不大,直接枚举最后一个数,找最大最小,然后求分数判断即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, x;
    cin >> n >> x;
    vector<int> a(n);
    for (int i = 0; i < n - 1; ++i)
        cin >> a[i];
    int ans = 0;
    auto ok = [&]() {
        auto tmp = a;
        sort(tmp.begin(), tmp.end());
        int sum =
            accumulate(tmp.begin(), tmp.end(), 0) - tmp.front() - tmp.back();
        return sum >= x;
    };
    for (; ans <= 100; ++ans) {
        a[n - 1] = ans;
        if (ok())
            break;
    }
    if (ans == 101)
        ans = -1;
    cout << ans << '\n';

    return 0;
}



C - 321-like Searcher (abc321 C)

题目大意

给定\(k\),问\(321-like\)的第 \(k\)小的数是多少。

\(321-like\)就是第一题的定义,从高位到低位逐数字递减。

解题思路

最大的是\(9876543210\),可以猜测数不多,直接搜索全部数出来,然后排序看第\(k\) 个是多少即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int k;
    cin >> k;
    LL s = 0;
    vector<LL> ans;
    function<void(int)> dfs = [&](int x) {
        s = s * 10 + x;
        ans.push_back(s);
        for (int i = x - 1; i >= 0; --i)
            dfs(i);
        s /= 10;
    };
    for (int i = 9; i >= 0; --i) {
        dfs(i);
    }
    sort(ans.begin(), ans.end());
    cout << ans[k] << '\n';

    return 0;
}



D - Set Menu (abc321 D)

题目大意

给定两个数组\(a,b\)和一个数\(p\),各从中取一个数\(x,y\),得到贡献 \(\min(x+y, p)\) 。问所有取法的贡献和。

解题思路

对数组\(b\)排序,枚举数组 \(a\),那么小于 \(p-a\)\(b\)的贡献是 \(a+b\),其余的贡献是 \(p\),因此二分找到这个界限,分别计算这两类的贡献和即可,前者是个关于\(b\)的前缀和,后者就是一个数组\(b\)\(\geq p-a\)的数量的统计。时间复杂度是 \(O(n\log m)\)

也可以对\(a,b\)都排序,此时\(a\)枚举从大到小, \(b\)枚举从小到大,双指针也行。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    LL p;
    cin >> n >> m >> p;
    vector<LL> a(n), b(m);
    vector<LL> sumb(m);
    for (auto& i : a)
        cin >> i;
    for (auto& i : b)
        cin >> i;
    sort(b.begin(), b.end());
    partial_sum(b.begin(), b.end(), sumb.begin());
    LL ans = 0;
    for (auto& i : a) {
        LL r = p - i;
        auto cnt = lower_bound(b.begin(), b.end(), r) - b.begin();
        ans += 1ll * i * cnt + (cnt ? sumb[cnt - 1] : 0) + 1ll * p * (m - cnt);
    }
    cout << ans << '\n';

    return 0;
}



E - Complete Binary Tree (abc321 E)

题目大意

给定一棵完全二叉树,问与点\(x\)的距离为\(k\)的个数。

\(t\)组。

解题思路

考虑点\(5\)距离为 \(k\)的点都在哪。

首先在以该点的子树内,深度为 \(k\)的点有 \(2^k\)(起始为\(0\)), 对应的标号都可以求出来,这样可以判断在\(n\)内的标号有多少个。

然后考虑该点的父亲的另一个节点(点\(4\))的子树内,此时我们要求的深度是 \(2^{k-2}\)的点的个数。

然后考虑该点的父亲的父亲的另一个节点(点\(3\))的子树内,此时我们要求的深度是\(2^{k-3}\)的点的个数。

不断往父亲考虑,因为每次往父亲走,点标号都会除以 \(2\),最多 \(\log\)次就考虑完了。

总的复杂度是 \(O(t\log n)\)

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;

    auto solve = [&](LL x, LL k, LL n) {
        if (k < 0)
            return 0ll;
        if (k >= 64)
            return 0ll;
        __int128 num = (1ll << k), l = x;
        l = (l << k);
        __int128 r = l + num - 1;
        if (l > n)
            return 0ll;
        LL ret = min(r, (__int128)n) - l + 1;
        return ret;
    };
    while (t--) {
        LL n, x, k;
        cin >> n >> x >> k;
        LL ans = 0;
        if (k)
            ans += solve(x, k, n);
        while (x > 1 && k > 0) {
            --k;
            ans += solve((x ^ 1), k - 1, n);
            x /= 2;
        }
        if (x && k == 0)
            ans++;
        cout << ans << '\n';
    }

    return 0;
}



F - #(subset sum = K) with Add and Erase (abc321 F)

题目大意

箱子,放球,拿球,球上有数,各不相同。

每次操作后,问里面球数和为\(k\)的方案数。

解题思路

不考虑拿走球的操作,每次放球,求方案数,就是一个经典的\(0/1\)背包。

\(dp[i]\)表示和为 \(j\)的方案数,考虑选不选这个球(其数字为\(x\)),则有 \(dp[i] = dp[i] + dp[i - x]\)

现在拿走这个球,得从中剔除选了这个球的方案数。

\(dp2[i]\)表示不选该球,和为 \(i\)的方案数。由于 \(dp[i]\)的方案包括两部分:选了该球和没选该球的。只要减去选了该球的方案数,那就是没选该球的方案数。而选了该球的方案数,其实就是 \(dp2[i-x]\),即选了这个球后,剩下的 \(i-x\)就是由不选该球的方案数组成,这恰好是我们定义的 \(dp2[i-x]\)的定义。

于是 \(dp2[i] = dp[i] - dp2[i - x]\)转移式即可。

时间复杂度是 \(O(qn)\)

这其实是最经典的退背包问题。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

const int mo = 998244353;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int q, k;
    cin >> q >> k;
    vector<int> dp(k + 1, 0);
    dp[0] = 1;
    while (q--) {
        string op;
        int x;
        cin >> op >> x;
        if (op[0] == '+') {
            for (int i = k; i >= x; --i) {
                dp[i] += dp[i - x];
                if (dp[i] >= mo)
                    dp[i] -= mo;
            }
        } else {
            vector<int> dp2(k + 1, 0);
            for (int i = 0; i <= k; ++i) {
                if (i < x) {
                    dp2[i] = dp[i];
                } else {
                    dp2[i] = dp[i] - dp2[i - x];
                    if (dp2[i] < 0)
                        dp2[i] += mo;
                }
            }
            dp.swap(dp2);
        }
        cout << dp[k] << '\n';
    }

    return 0;
}



G - Electric Circuit (abc321 G)

题目大意

给定\(n\)个部件和 \(m\)条线。部件有接口,有红蓝两色,数量都是\(m\)。一条线链接的两个接口必须不同颜色,但可以同个部件。

将部件视为点,线视为边,随机连线,问联通块的期望个数。

解题思路

<++>文章来源地址https://www.toymoban.com/news/detail-711992.html

神奇的代码



到了这里,关于AtCoder Beginner Contest 321的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AtCoder Beginner Contest 320

    给定 (a,b) ,输出 (a^b + b^a) 。 因为数不超过 (10) ,可以直接用 pow 计算然后转成 (int) 。不会有精度损失。 神奇的代码 给定一个字符串 (s) ,求长度最长的回文串。 因为长度只有 (100) ,可以直接枚举子串,然后暴力判断是不是回文串(翻转后是否和自身相同),复杂

    2024年02月08日
    浏览(38)
  • AtCoder Beginner Contest 348

    给定 (n) ,输出 (ooxooxoox...) ,长度为 (n) 。 按题意模拟即可。 神奇的代码 给定 (n) 个点,对每个点,求出与其距离最远的点的下标。 (n) 只有 (100) ,对于每个点,花 (O(n)) 遍历每个点最大化距离,时间复杂度为 (O(n^2)) 。 神奇的代码 (n) 个豌豆,每个豌豆有美味值

    2024年04月08日
    浏览(42)
  • AtCoder Beginner Contest 314

    怎么好多陌生单词 审核怎么这么逆天,半小时还没审完 给定 (pi) 的值以及数 (n) ,要求保留 (n) 位小数输出,不四舍五入。 字符串形式储存然后截取末尾即可。 神奇的代码 (n) 个人玩轮盘赌游戏,简单说就是一个转盘有 (37) 个数字以及一个箭头,箭头会等概率停在某

    2024年02月13日
    浏览(40)
  • AtCoder Beginner Contest 335

    给定一个字符串,将最后一位改成 4 。 模拟即可。 神奇的代码 给定 (n) ,按字典序输出非负整数 (i,j,k) ,使得 (i+j+kleq n) (n) 只有 (21) ,直接 (O(n^3)) 枚举判断即可。 神奇的代码 二维网格,贪吃蛇,移动,进行 (q) 次操作,分两种 指定贪吃蛇下一步移动的方向 指定

    2024年01月19日
    浏览(32)
  • AtCoder Beginner Contest 322

    给定一个字符串,找到最先出现 ABC 的位置。 直接查找判断即可。 神奇的代码 给定字符串 s 和 t ,问 s 是不是 t 的前缀和后缀。 根据前后缀定义判断即可。这里试了下 python 神奇的代码 (n) 天,有 (m) 天会放烟花。 问每一天,距离未来最近的放烟花的天数。 两个双指针一

    2024年02月08日
    浏览(33)
  • AtCoder Beginner Contest 301

    给定一个字符串表示高桥和青木每局的获胜情况。 如果高桥获胜局数多,或者两个胜局相等,但高桥率先取得那么多胜场,则高桥获胜,否则青木获胜。 问谁获胜。 按照题意,统计两者的获胜局数比较即可。 如果两者局数相等,可以看最后一局谁胜,青木胜则意味着高桥率

    2024年02月04日
    浏览(55)
  • AtCoder Beginner Contest 303

    给定两个字符串,问这两个字符串是否相似。 两个字符串相似,需要每个字母,要么完全相同,要么一个是 1 一个是 l ,要么一个是 0 一个是 o 按照题意模拟即可。 可以将全部 1 换成 l ,全部 0 换成 o ,再判断相等。 神奇的代码 给定 m 个 n 的排列,问有多少对 ((i, j),i j

    2024年02月07日
    浏览(35)
  • AtCoder Beginner Contest 330

    给定 (n) 个学生的分数,以及及格分 (x) ,问多少人及格了。 依次判断即可。 神奇的代码 回答 (n) 个问题,每个问题给定 (a,l,r) ,问函数 (f(x) = |x - a|) 在 ([l,r]) 的最小值。 全定义域下,最小值显然在 (x=a) 取得。绝对值函数图像是 (V) 型。 现在限定在 ([l,r]) ,则

    2024年02月05日
    浏览(116)
  • AtCoder Beginner Contest 318

    咕咕咕,总力战还没打,凹不过卷狗,躺了.jpg 给定 (n, m, p) ,问有多少个 (i) 满足 (0 m+pi leq n) 减去初始的 (m) ,剩下的就是看 (p) 的倍数个数。 神奇的代码 一个二维空间,有 (n) 个矩形覆盖。 问有多大的空间被覆盖了。重复覆盖算一次。 空间大小只有 (100) ,矩形

    2024年02月10日
    浏览(40)
  • AtCoder Beginner Contest 334

    给定两个数 (b,g(b neq g)) ,如果 (b) 大则输出 Bat ,否则输出 Glove 。 比较大小输出即可。 神奇的代码 给定 (a,m,l,r) ,问有多少个整数 (k) 满足 (l leq a + mk leq r) . 对不等式化简一下即为 (frac{l - a}{m} leq k leq frac{r - a}{m}) 的整数个数。 答案就是 (lfloor frac{r - a}{m} r

    2024年02月04日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包