第十一届蓝桥杯大赛软件类决赛(C/C++ 大学A组)
Posted 肖有量
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十一届蓝桥杯大赛软件类决赛(C/C++ 大学A组)相关的知识,希望对你有一定的参考价值。
蓝桥杯 2020年国赛真题
C/C++ 大学A组
- 试题 A: 合数个数
- 试题 B: 含 2 天数
- 试题 C: 本质上升序列
- 试题 D: 咫尺天涯
- 试题 E: 玩具蛇
- 试题 F: 皮亚诺曲线距离
- 试题 G: 出租车
- 试题 H: 答疑
- 试题 I: 奇偶覆盖
- 试题 J: 蓝跳跳
试题 A: 合数个数
本题总分: 5 5 5 分
【问题描述】
一个数如果除了 1 1 1 和自己还有其他约数,则称为一个合数。例如: 1 , 2 , 3 1, 2, 3 1,2,3 不是合数, 4 , 6 4, 6 4,6 是合数。
请问从 1 1 1 到 2020 2020 2020 一共有多少个合数。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
1713
#include <stdio.h>
const int N = 2020;
int ans, factor[N + 1];
int main()
for (int i = 2; i <= N; ++i)
if (factor[i]) ++ans;
else
for (int j = i; j <= N; j += i)
factor[j] = 1;
printf("%d", ans);
这码风,程序设计老师看了直摇头。
试题 B: 含 2 天数
本题总分: 5 5 5 分
【问题描述】
小蓝特别喜欢 2 2 2,今年是公元 2020 2020 2020 年,他特别高兴,因为每天日历上都可以看到 2。
如果日历中只显示年月日,请问从公元 1900 1900 1900 年 1 1 1 月 1 1 1 日到公元 9999 9999 9999 年 12 12 12 月 31 31 31 日,一共有多少天日历上包含 2 2 2。即有多少天中年月日的数位中包含数字 2 2 2。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
1994240
#include <stdio.h>
int ans, days[]0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31;
int isLeap(int year) return !(year % 100 ? year % 4 : year % 400);
int contain2(int num) do if (num % 10 == 2) return 1; while (num /= 10);
int main()
for (int year = 1900; year <= 9999; ++year)
if (isLeap(year)) days[2] = 29;
for (int month = 1; month <= 12; ++month)
for (int day = 1; day <= days[month]; ++day)
if (contain2(year) || contain2(month) || contain2(day)) ++ ans;
days[2] = 28;
printf("%d", ans);
摇头。
试题 C: 本质上升序列
本题总分: 10 10 10 分
【问题描述】
小蓝特别喜欢单调递增的事物。
在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。
例如,在字符串 l a n q i a o \\mathrmlanqiao lanqiao 中,如果取出字符 n \\mathrmn n 和 q \\mathrmq q,则 n q \\mathrmnq nq 组成一个单调递增子序列。类似的单调递增子序列还有 l n q \\mathrmlnq lnq、 i \\mathrmi i、 a n o \\mathrmano ano 等等。
小蓝发现,有些子序列虽然位置不同,但是字符序列是一样的,例如取第二个字符和最后一个字符可以取到
a
o
\\mathrmao
ao,取最后两个字符也可以取到
a
o
\\mathrmao
ao。
小蓝认为他们并没有本质不同。
对于一个字符串,小蓝想知道,本质不同的递增子序列有多少个?
例如,对于字符串 l a n q i a o \\mathrmlanqiao lanqiao,本质不同的递增子序列有 21 21 21 个。它们分别是 l \\mathrml l、 a \\mathrma a、 n \\mathrmn n、 q \\mathrmq q、 i \\mathrmi i、 o \\mathrmo o、 l n \\mathrmln ln、 a n \\mathrman an、 l q \\mathrmlq lq、 a q \\mathrmaq aq、 n q \\mathrmnq nq、 a i \\mathrmai ai、 l o \\mathrmlo lo、 a o \\mathrmao ao、 n o \\mathrmno no、 i o \\mathrmio io、 l n q \\mathrmlnq lnq、 a n q \\mathrmanq anq、 l n o \\mathrmlno lno、 a n o \\mathrmano ano、 a i o \\mathrmaio aio。
请问对于以下字符串(共 200 200 200 个小写英文字母,分四行显示):(如果你把以下文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 inc.txt,内容与下面的文本相同)
tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhf
iadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqij
gihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmad
vrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl
本质不同的递增子序列有多少个?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
3616159
动态规划
首先考虑上升子序列问题,即子串可以相同的情况。
设 f i f_i fi 为以字符串 S [ 1 , n ] S[1,n] S[1,n] 第 i i i 个字符结尾的最长递增子序列的个数,则总个数为 ∑ i = 1 n f i \\sum_i=1^nf_i ∑i=1nfi,状态转移方程为 f i = ∑ j = 1 i − 1 f j ( S [ i ] > S [ j ] ) f_i = \\sum_j=1^i-1f_j(S[i] > S[j]) fi=∑j=1i−1fj(S[i]>S[j])。
为了避免出现重复子串,考虑互斥的划分方式,
有状态 f i , c f_i,c fi,c 表示到第 i i i 个字符为止,以 c c c 结尾的本质不同子串的个数为多少,显然答案为 ∑ c f n , c \\sum_c f_n,c ∑cfn,c。
可是如何保证不重不漏呢?
对于 c ≠ S [ i ] c \\neq S[i] c=S[i],显然有 f i , c = f i − 1 , c f_i,c = f_i - 1, c fi,c=fi−1,c,而对于 c = S [ i ] c = S[i] c=S[i] 的情况,考虑重新统计即 f i , c = ∑ c ′ = 1 c − 1 f i − 1 , c ′ f_i,c = \\sum_c'=1^c-1f_i-1,c' fi,c=∑c′=1c−1fi−1,c′,不重是做到了,即可不重不漏。
证明半天证明了一坨屎,其实可以用反证法,但反证太无聊了。
#include <iostream>
std::string s = "$", buf;
int dp[0xff], ans;
int main()
freopen("inc.txt", "r", stdin);
while (std::cin >> buf) s += buf;
for (int i = 1; i <= 200; ++i)
ans -= dp[s[i]], dp[s[i]] = 1;
for (int j = s[i] - 1; j >= 'a'; --j) dp[s[i]] += dp[j];
ans += dp[s[i]];
printf("%d", ans);
试题 D: 咫尺天涯
本题总分: 10 10 10 分
【问题描述】
皮亚诺曲线是一条平面内的曲线。
下图给出了皮亚诺曲线的 1 1 1 阶情形,它是从左下角出发,经过一个 3 × 3 3 × 3 3×2019 第十届蓝桥杯大赛软件赛决赛,国赛,C/C++大学B组题解
2021 第十二届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B 组
第十一届蓝桥杯大赛软件类省赛第二场C/C++大学B组(python解答)
2021年第十二届蓝桥杯大赛软件赛决赛C/C++大学A组 个人部分题解