AtCoder Beginner Contest 336 A-E 题解

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

比赛链接:https://atcoder.jp/contests/abc336
比赛时间:2024 年 1 月 14 日 20:00-21:40

A题:Long Loong

标签:模拟
题意:给定一个 n n n,输出 L L L n n n o o o n g ng ng
题解:按题意模拟即可。
代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    cout << "L";
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cout <<  "o";
    cout << "ng";
    return 0;
}

B题:CTZ

标签:模拟
题意:给定一个十进制数 n n n,求该数转换成 2 2 2进制之后末尾连续 0 0 0的个数。( 1 < = n < = 1 0 9 1<=n<=10^9 1<=n<=109
题解:模拟,二进制转换,累计一下末尾 0 0 0个数,直到不是 0 0 0,跳出循环。
代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, c = 0;
    cin >> n;
    while (n) {
        if (n % 2 == 0) c++;
        else break;
        n /= 2;
    }
    cout << c;
    return 0;
}

C题:Even Digits

标签:思维、数学
题意:给出定义十进制数 x x x的所有数位都是偶数(即 0 、 2 、 4 、 6 、 8 0、2、4、6、8 02468)的时候称为 “好整数”,给定一个 n n n,求第 n n n小的 “好整数”。( 1 < = n < = 1 0 12 1<=n<=10^{12} 1<=n<=1012
前几个 “好整数” 分别为 0 、 2 、 4 、 6 、 8 、 20 、 22 、 24 、 26 、 28... 0、2、4、6、8、20、22、24、26、28... 024682022242628...
题解:每个数位都是最多 5 5 5种可能,我们可以先求出超过 n n n需要的位数,比如第 8 8 8小的,一位最多只有 5 5 5种,两位能到 25 25 25种,所以至少得两位。
接着我们再求目前当前这位对应的到底是 0 、 2 、 4 、 6 、 8 0、2、4、6、8 02468中的哪一个。
比如第 8 8 8小的,我们求第一位上的数字的时候,
1 ∗ 5 < 8 1*5<8 15<8
2 ∗ 5 > 8 2*5>8 25>8
所以我们能确定,第一位上的数字是 2 2 2。对于后面的第二位来说,我们需要把刚刚第一位带来的整个部分的个数给减掉, 8 − 5 = 3 8-5=3 85=3
1 ∗ 1 < 3 1*1<3 11<3
1 ∗ 2 < 3 1*2<3 12<3
1 ∗ 3 > = 3 1*3>=3 13>=3
所以第二位上的数字是 4 4 4
代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    long long n, k = 1, c = 0;
    cin >> n;
    while (k <= n) {
        k *= 5;
        c++;
    }
    for (int i = 1; i <= c; i++) {
        k /= 5;
        for (int j = 1; j <= 5; j++) {
            if (j * k >= n) {
                n -= (j-1) * k;
                cout << (j - 1) * 2;
                break;
            }
        }
    }
    return 0;
}

D题:Pyramid

标签:动态规划、前缀和
题意:金字塔型序列: 1 、 2... k − 1 、 k 、 k − 1...2 、 1 1、2...k-1、k、k-1...2、1 12...k1kk1...21。给定一个长度为 n n n的序列 a i a_i ai,可以进行重复性的两种操作:

  1. 将序列中某个数的大小减一
  2. 删除第一个或最后一个数

求能够形成的金字塔型序列的最大长度。( 1 < = n < = 2 ∗ 1 0 5 , 1 < = a i < = 1 0 9 1<=n<=2*10^{5},1<=a_i<=10^9 1<=n<=21051<=ai<=109
题解:比较常见的套路,洛谷也有类似的题:P1091 合唱队形
从左往右维护一个 p r e [ i ] pre[i] pre[i]:以 a i a_i ai作为结尾的最长左金字塔序列的长度
从右往左维护一个 s u f [ i ] suf[i] suf[i]:以 a i a_i ai作为结尾的最长右金字塔序列的长度
我们以 p r e [ i ] pre[i] pre[i]为例,分别来观察一下
例子 1 1 1 1 、 2 、 3 1、2、3 123
例子 2 2 2 1 、 2 、 2 1、2、2 122
例子 3 3 3 3 、 1 、 2 3、1、2 312
按照题目中能把数变小和删除前后数字的操作,能推出当前的 p r e [ i ] pre[i] pre[i]要从前面的 p r e [ i − 1 ] pre[i-1] pre[i1]和当前 a i a_i ai较小的那个推过来:
p r e [ i ] = m i n ( p r e [ i − 1 ] + 1 , a [ i ] ) pre[i] = min(pre[i - 1] + 1, a[i]) pre[i]=min(pre[i1]+1,a[i])
s u f suf suf同理,最终枚举每个数作为金字塔尖,左边金字塔序列长度和右边金子塔序列长度中取小的那个能够形成的金字塔序列长度,然后维护一个最大值。
代码

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
typedef long long ll;
ll a[N], pre[N], suf[N];

int main() {
    ll n, ans = 0;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        pre[i] = min(pre[i - 1] + 1, a[i]);
    }
    for (int i = n; i >= 1; i--) {
        suf[i] = min(suf[i + 1] + 1, a[i]);
    }
    for (int i = 1; i <= n; i++) {
        ans = max(ans, min(pre[i], suf[i]));
    }
    cout << ans;
    return 0;
}

E题:Digit Sum Divisible

标签:数位 d p dp dp
题意:给定一个 n n n,求小于等于 n n n的数中有多少个能被自己的位数之和整除。( 1 < = n < = 1 0 14 1<=n<=10^{14} 1<=n<=1014
**题解:**数位 d p dp dp模版题, d p [ p o s ] [ s u m ] [ m o d ] dp[pos][sum][mod] dp[pos][sum][mod]表示当第 p o s pos pos位各位数字之和为 s u m sum sum除原数的余数是 m o d mod mod且有没超出边界时候的个数。
代码文章来源地址https://www.toymoban.com/news/detail-803644.html

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
ll n, m, cnt = 0;
// dp[i][j][k]: 第i位 当前数字和为j 取模结果为k的个数
ll a[20], dp[20][10*20][10*20];

ll dfs(ll pos, ll sum, ll mod, ll flag) {
    if (sum > m) return 0;
    if (pos == 0) return sum == m && mod == 0;
    if (!flag && dp[pos][sum][mod] != -1) return dp[pos][sum][mod];
    ll x = flag ? a[pos] : 9;
    ll ans = 0;
    for (ll i = 0; i <= x; i++) {
        ans += dfs(pos - 1, sum + i, (mod * 10 + i) % m, flag && (i == a[pos]));
    }
    if (!flag) dp[pos][sum][mod] = ans;
    return ans;
}

int main() {
    cin >> n;
    while (n) {
        a[++cnt] = n % 10;
        n /= 10;
    }
    ll res = 0;
    for (int i = 1; i <= 9 * cnt; i++) {
        m = i;
        memset(dp, -1, sizeof(dp));
        res += dfs(cnt, 0, 0, 1);
    }
    cout << res;
    return 0;
}

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

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

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

相关文章

  • AtCoder Beginner Contest 336 E - Digit Sum Divisible

    E - Digit Sum Divisible 题意 定义一个正整数 x x x 为 g o o d good g oo d 当且仅当: x x x 能被它的数位和 整除 统计小于等于 N N N 的 g o o d good g oo d 正整数数量 思路 这道题关键是要观察到在 N ≤ 1 0 14 N leq 10^{14} N ≤ 1 0 14 的限制下,数位和种类是有限的:最多只有 9 × log ⁡ 10 1 0 1

    2024年01月25日
    浏览(41)
  • AtCoder Beginner Contest 317 题解 ABCDE | JorbanS

    题意 求权值和最大的一条路径 Tag dfs 题意 n × m n×m n × m 的迷宫, . 代表可以走, # 代表障碍物, ^v 代表射线,射线方向不能走,知道射线遇到非 . 的格子,求最短路 Tag bfs

    2024年02月10日
    浏览(36)
  • AtCoder Beginner Contest 302 H. Ball Collector 题解

    为了更好的阅读体验,请单击这里 AtCoder Beginner Contest 302 H. Ball Collector 题意跳过。 可以视作将 (a_i, b_i) 之间连了一条边,然后 (a_i, b_i) 之间只能选一个等价于对于一条边只能选择其一个端点。那么对于只包含树的联通块而言,如果都选择儿子节点,那么会有一个根节点无

    2024年02月06日
    浏览(39)
  • Atcoder Beginner Contest 324 G Generate Arrays 题解-Treap

    为了更好的阅读体验,请点击这里 题目链接 套上平衡树板子就能做的很快的题,然后因为是指针存树,因此交换只需要把序列大小较小的挨个拿出来插到相应的地方即可。复杂度 (O(N log^2 N)) 。 但是一定要记住 不可以直接使用 std::swap 交换包含带有指针的类的实例(如代码

    2024年02月08日
    浏览(44)
  • Atcoder Beginner Contest 324 F Beautiful Path 题解-分数规划

    为了更好的阅读体验,请点击这里 分数规划小技巧: 尽可能将式子写成存在某种取值,使得不等式成立的形式。 不然可能需要绕几个弯才能想出来。 题目链接 题目大意:给出一个 DAG,每条边有一个 (b_i, c_i) ,保证从编号小的边向编号大的边连边,且 (1) 到 (n) 必有路径

    2024年02月08日
    浏览(39)
  • AtCoder Beginner Contest 302 H. Ball Collector 题解 可撤销并查集

    为了更好的阅读体验,请单击这里 AtCoder Beginner Contest 302 H. Ball Collector 题意跳过。 可以视作将 (a_i, b_i) 之间连了一条边,然后 (a_i, b_i) 之间只能选一个等价于对于一条边只能选择其一个端点。那么对于只包含树的联通块而言,如果都选择儿子节点,那么会有一个根节点无

    2024年02月06日
    浏览(35)
  • Atcoder Beginner Contest 321 G - Electric Circuit 题解 - 状压dp | 指定最低位

    为了更好的阅读体验,请点击这里 题目链接:G - Electric Circuit 看到了 (N) 的数据范围,因此是显然的状压 dp。 不妨设 (f_S) 为仅使用 (S) 集合中的所有点,能够连成恰好 (1) 个连通块的方案数。 (g_S) 为仅使用 (S) 集合中的所有点的方案数,其中 (cntr(S)) 在 (S) 中为

    2024年02月05日
    浏览(54)
  • AtCoder Beginner Contest 310

    感觉F又双叒叕写复杂了 点杯咖啡,要 (p) 元,但可以用一个优惠券,使得咖啡只要 (q) 元,但你需要额外购买 (n) 个商品中(价格为 (a_i) )的一个。 问点杯咖啡的最小价格。 考虑直接买还是使用优惠券,使用优惠券的话就选 (n) 个商品中价格最小的。 两种情况取最小

    2024年02月16日
    浏览(28)
  • 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)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包