第十四届蓝桥杯大赛软件赛省赛(C/C++ 研究生组)

这篇具有很好参考价值的文章主要介绍了第十四届蓝桥杯大赛软件赛省赛(C/C++ 研究生组)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

蓝桥杯 2023年省赛真题
C/C++ 大学G组

 试题 A: 工作时长
 试题 B: 与或异或
 试题 C: 翻转
 试题 D: 阶乘的和
 试题 E: 公因数匹配
 试题 F: 奇怪的数
 试题 G: 太阳
 试题 H: 子树的大小
 试题  I: 高塔
 试题 J: 反异或 01 串


除去第 F \rm F F 题,其他题目在其他组别都有出现过,这里就不重写了。


奇怪的数

时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 15 15 15


【问题描述】

  小蓝最近在找一些奇怪的数,其奇数数位上是奇数,而偶数数位上是偶数。同时,这些数的任意 5 5 5 个连续数位的和都不大于 m m m
  例如当 m = 9 m = 9 m=9 时, 10101 10101 10101 12303 12303 12303 就是奇怪的数,而 12345 12345 12345 11111 11111 11111 则不是。
  小蓝想知道一共有多少个长度为 n n n 的上述的奇怪的数。你只需要输出答案对 998244353 998244353 998244353 取模的结果。

【输入格式】

  输入一行包含两个整数 n , m n, m n,m,用一个空格分隔。

【输出格式】

  输出一行包含一个整数表示答案。

【样例输入】

5 5

【样例输出】

6

【评测用例规模与约定】

  对于 30 % 30\% 30% 的评测用例, n ≤ 12 n ≤ 12 n12
  对于 60 % 60\% 60% 的评测用例, n ≤ 5000 n ≤ 5000 n5000
  对于所有评测用例, 5 ≤ n ≤ 2 × 1 0 5 , 0 ≤ m ≤ 50 5 ≤ n ≤ 2 × 10^5,0 ≤ m ≤ 50 5n2×1050m50


动态规划


  因为是要校验连续的 5 5 5 个数位上的数字之和是否大于 m m m,自然能设计出状态 f i , a , b , c , d f_{i,a,b,c,d} fi,a,b,c,d,表示第 i − 3 i-3 i3 个数位上的数字为 a a a i − 2 : b i-2:b i2:b i − 1 : c i-1:c i1:c i : d i:d i:d 的奇怪的数有多少个,容易找到状态转移方程: f i , a , b , c , d = ∑ f i − 1 , e , a , b , c , a + b + c + d + e ≤ m . f_{i,a,b,c,d}=\sum f_{i-1,e,a,b,c},a+b+c+d+e\leq m. fi,a,b,c,d=fi1,e,a,b,c,a+b+c+d+em.  转移复杂度为 O ( n D 5 ) O(nD^5) O(nD5),其中 D = 5 D=5 D=5 即每个数位可能的取值的个数,这样看来复杂度就超了, 1 s \rm 1s 1s 指定是跑不出来,于是考虑维护 f f f 在第二维的前缀和,具体地说我们记: g i , a , b , c , d = ∑ j = 0 a f i , j , b , c , d . g_{i,a,b,c,d}=\sum_{j=0}^af_{i,j,b,c,d}. gi,a,b,c,d=j=0afi,j,b,c,d.  则状态转移方程可改写为: g i , a , b , c , d = g i , a − 1 , b , c , d + g i − 1 , max ⁡ ( 0 , min ⁡ ( 9 , m − a − b − c − d ) ) , a , b , c . g_{i,a,b,c,d}=g_{i,a-1,b,c,d}+g_{i-1,\max(0,\min(9,m-a-b-c-d)),a,b,c}. gi,a,b,c,d=gi,a1,b,c,d+gi1,max(0,min(9,mabcd)),a,b,c.  转移复杂度为 O ( n D 4 ) O(nD^4) O(nD4) 1 s \rm 1s 1s 有那么一点极限,标程很有可能不是动规。还有就是在实现时为了使 D = 5 D=5 D=5,转移过程会有一定的微调,具体看代码吧。

#include <stdio.h>

const int M = 12, mod = 998244353;

int n, m, ans, g[2][M][M][M][M];

int main() {
    scanf("%d %d", &n, &m);
    int p = 1, q = 0;
    for (int a = p; a < 10; a += 2)
        for (int b = q; b < 10; b += 2)
            for (int c = p; c < 10; c += 2)
                for (int d = q; d < 10; d += 2) {
                    g[0][a + 2][b][c][d] = g[0][a][b][c][d] + (a + b + c + d <= m);
                }
    for (int i = 5; i <= n; ++i) {
        p ^= 1, q ^= 1;
        for (int a = p; a < 10; a += 2)
            for (int b = q; b < 10; b += 2)
                for (int c = p; c < 10; c += 2)
                    for (int d = q; d < 10; d += 2) {
                        int f = m - a - b - c - d;
                        if (q != (f & 1)) --f;
                        if (f > 8 + p) f = 8 + q;
                        g[i & 1][a + 2][b][c][d] = (g[i & 1][a][b][c][d] + (f < q ? 0 : g[~i & 1][f + 2][a][b][c])) % mod;
                    }
    }
    for (int b = q; b < 10; b += 2)
        for (int c = p; c < 10; c += 2)
            for (int d = q; d < 10; d += 2) {
                int f = m - b - c - d;
                if (f < p) continue;
                if (p != (f & 1)) --f;
                if (f > 8 + p) f = 8 + p;
                ans = (ans + g[n & 1][f + 2][b][c][d]) % mod;
            }
    printf("%d", ans);
}

  输入200000 50 4000 4000 4000 R y z e n \rm Ryzen Ryzen 刚好在 1 s \rm 1s 1s 跑完,这放在评测机上不开 O \rm\small O O 2 2 2 就超时了。推了半天式子也没什么结果,不过有一种实在的优化方案是:
  记一个长度为 4 4 4 奇偶交替数 n n n a b c d abcd abcd,它的数位之和为 s = a + b + c + d s=a+b+c+d s=a+b+c+d,我们记 n n n 的逆 n ′ = ( 9 − a ) ( 9 − b ) ( 9 − c ) ( 9 − d ) n'=(9-a)(9-b)(9-c)(9-d) n=(9a)(9b)(9c)(9d) ,则逆的数位之和为 s ′ = 36 − s s'=36-s s=36s,显然 n n n 的全集的按数位之和划分,它的大小以 18 18 18 为中点对称。如果输入的 m m m 在对称点以左,我们按原问题求解,在对称点及对称点以右我们求其逆问题,即一个数 S S S,为长度为 n n n 且存在连续 5 5 5 个数位之和大于 m m m 的数的个数,此时答案为 5 n − S 5^n-S 5nS,这样下来状态转移的次数减少一半,可以在时间限制内计算出答案。
  不过相应的代码量翻倍,没这个必要,还是题太臭了。文章来源地址https://www.toymoban.com/news/detail-473445.html

到了这里,关于第十四届蓝桥杯大赛软件赛省赛(C/C++ 研究生组)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 第十四届蓝桥杯大赛软件赛省赛(C/C++B组)

    目前除 B、F题未补,其余题均已更完,经非官方数据测试均可AC。欢迎交流   小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的 范围之内。数组中的元素从左至右如下所示: 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0

    2023年04月13日
    浏览(41)
  • 第十四届蓝桥杯大赛软件赛省赛(C/C++ 大学A组)

    本题总分: 5 5 5 分 【问题描述】   小蓝认为如果一个数含有偶数个数位,并且前面一半的数位之和等于后面一半的数位之和,则这个数是他的幸运数字。例如 2314 2314 2314 是一个幸运数字,因为它有 4 4 4 个数位,并且 2 + 3 = 1 + 4 2 + 3 = 1 + 4 2 + 3 = 1 + 4 。现在请你帮他计算从

    2024年02月05日
    浏览(54)
  • 第十四届蓝桥杯大赛软件赛省赛(C/C++ 大学C组)

    本题总分: 5 5 5 分 【问题描述】   求 1 1 1 (含)至 20230408 20230408 20230408 (含)中每个数的和。 【答案提交】   这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。 2046347140384

    2024年02月04日
    浏览(48)
  • 第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组

    注意!!!!!!!!!!这篇题解为赛时的个人做法,不代表是正确的,仅供参考。 更新:思路上应该都对,很多题都有细节错误,代码不用看了,太久没敲代码了(- -) 更新2:代码除了岛屿的都改好了,整数删除常数有点大,可能会t,赛时的代码一堆错误,还是对自己的文

    2024年02月05日
    浏览(43)
  • 第十四届蓝桥杯大赛软件赛省赛(C/C++ 大学B组)

    目前除 B、F题未补,其余题均已更完,经非官方数据测试均可AC。欢迎交流   小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的 范围之内。数组中的元素从左至右如下所示: 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0

    2024年02月02日
    浏览(47)
  • 第十四届蓝桥杯大赛软件赛省赛-试题 B---01 串的熵 解题思路+完整代码

    欢迎访问个人网站来查看此文章:http://www.ghost-him.com/posts/db23c395/ 对于一个长度为 n 的 01 串 S = x 1 x 2 x 3 . . . x n S = x_{1} x_{2} x_{3} ... x_{n} S = x 1 ​ x 2 ​ x 3 ​ ... x n ​ ,香农信息熵的定义为 H ( S ) = − ∑ 1 n p ( x i ) l o g 2 ( p ( x i ) ) H(S ) = − {textstyle sum_{1}^{n}} p(x_{i})log_{2} (p

    2023年04月10日
    浏览(44)
  • 第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 A 组 D题

    输入一行包含一个长度为 n 的字符串表示 num(仅包含数字字符 0 ∼ 9), 从左至右下标依次为 0 ∼ n − 1。 输出一行包含一个整数表示答案。 210102 8一共有 8 种不同的方案: 1)所选择的子串下标为 0 ∼ 1 ,反转后的 numnew = 120102 210102 ; 2)所选择的子串下标为 0 ∼ 2 ,反转

    2023年04月11日
    浏览(40)
  • 第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 A 组 C题

    输入一行包含两个整数 L, R,用一个空格分隔。 输出一行包含一个整数满足题目给定条件的 x 的数量。 1 5 4 对于 40% 的评测用例,L R ≤ 5000 ; 对于所有评测用例,1 ≤ L ≤ R ≤ 10^9 。 暴力没说的,y肯定在l-r之间。同时要想到x=(y+z)(y-z)那么x就只能是y+z的倍数。 1.使用了

    2023年04月15日
    浏览(97)
  • 第十三届蓝桥杯大赛软件赛省赛(C++研究生组)

    可以证明,只要首先裁剪最外围的 4 4 4 条边,之后无论怎样裁剪,次数都是最少。对于 n n n 行 m m m 列的二维码,至少需要裁剪 n m + 3 nm + 3 nm + 3 次,因此答案为 20 × 22 + 3 = 443 20times 22+3=443 20 × 22 + 3 = 443 。 证明:只需证明裁掉边界后至少还需裁剪 n m − 1 nm-1 nm − 1 次。 n

    2023年04月10日
    浏览(46)
  • 第十四届蓝桥杯大赛软件组省赛 Python大学A组 个人暴力题解

    4.23 update: 省一咯 Powered by: NEFU AB-IN 博主个人的暴力题解,基本很少是正解,求轻喷 题意 思路 模拟即可,本身想用Python自带的datetime库,结果发现年不能开那么大,就直接手写了 代码 题意 思路 DFS爆搜即可 代码 题意 思路 直接没思路,一看到数据范围瞬间怂了,脑子里想的

    2023年04月09日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包