蓝桥杯 2020年国赛真题
C/C++ 大学A组

  • 试题 A: 合数个数
  • 试题 B: 含 2 天数
  • 试题 C: 本质上升序列
  • 试题 D: 咫尺天涯
  • 试题 E: 玩具蛇
  • 试题 F: 皮亚诺曲线距离
  • 试题 G: 出租车
  • 试题 H: 答疑
  • 试题  I: 奇偶覆盖
  • 试题 J: 蓝跳跳

  蓝桥杯个人赛软件类历届真题及其解析


试题 A: 合数个数

本题总分:555 分


【问题描述】

  一个数如果除了 111 和自己还有其他约数,则称为一个合数。例如:1,2,31, 2, 31,2,3 不是合数,4,64, 64,6 是合数。

  请问从 111 到 202020202020 一共有多少个合数。

【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


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;elsefor (int j = i; j <= N; j += i)factor[j] = 1;printf("%d", ans);
}

  这码风,程序设计老师看了直摇头。


试题 B: 含 2 天数

本题总分:555 分


【问题描述】

  小蓝特别喜欢 222,今年是公元 202020202020 年,他特别高兴,因为每天日历上都可以看到 2。

  如果日历中只显示年月日,请问从公元 190019001900 年 111 月 111 日到公元 999999999999 年 121212 月 313131 日,一共有多少天日历上包含 222。即有多少天中年月日的数位中包含数字 222。


【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


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: 本质上升序列

本题总分:101010 分


【问题描述】

  小蓝特别喜欢单调递增的事物。

  在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。

  例如,在字符串 lanqiao\mathrm{lanqiao}lanqiao 中,如果取出字符 n\mathrm{n}n 和 q\mathrm{q}q,则 nq\mathrm{nq}nq 组成一个单调递增子序列。类似的单调递增子序列还有 lnq\mathrm{lnq}lnq、i\mathrm{i}i、ano\mathrm{ano}ano 等等。

  小蓝发现,有些子序列虽然位置不同,但是字符序列是一样的,例如取第二个字符和最后一个字符可以取到 ao\mathrm{ao}ao,取最后两个字符也可以取到 ao\mathrm{ao}ao。
  小蓝认为他们并没有本质不同。

  对于一个字符串,小蓝想知道,本质不同的递增子序列有多少个?

  例如,对于字符串 lanqiao\mathrm{lanqiao}lanqiao,本质不同的递增子序列有 212121 个。它们分别是 l\mathrm{l}l、a\mathrm{a}a、n\mathrm{n}n、q\mathrm{q}q、i\mathrm{i}i、o\mathrm{o}o、ln\mathrm{ln}ln、an\mathrm{an}an、lq\mathrm{lq}lq、aq\mathrm{aq}aq、nq\mathrm{nq}nq、ai\mathrm{ai}ai、lo\mathrm{lo}lo、ao\mathrm{ao}ao、no\mathrm{no}no、io\mathrm{io}io、lnq\mathrm{lnq}lnq、anq\mathrm{anq}anq、lno\mathrm{lno}lno、ano\mathrm{ano}ano、aio\mathrm{aio}aio。

  请问对于以下字符串(共 200200200 个小写英文字母,分四行显示):(如果你把以下文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 inc.txt,内容与下面的文本相同)

tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhf
iadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqij
gihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmad
vrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl

  本质不同的递增子序列有多少个?


【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


3616159


动态规划


  首先考虑上升子序列问题,即子串可以相同的情况。

  设 fif_ifi​ 为以字符串 S[1,n]S[1,n]S[1,n] 第 iii 个字符结尾的最长递增子序列的个数,则总个数为 ∑i=1nfi\sum_{i=1}^nf_i∑i=1n​fi​,状态转移方程为 fi=∑j=1i−1fj(S[i]>S[j])f_i = \sum_{j=1}^{i-1}f_j(S[i] > S[j])fi​=∑j=1i−1​fj​(S[i]>S[j])。

  为了避免出现重复子串,考虑互斥的划分方式,

  有状态 fi,cf_{i,c}fi,c​ 表示到第 iii 个字符为止,以 ccc 结尾的本质不同子串的个数为多少,显然答案为 ∑cfn,c\sum_c f_{n,c}∑c​fn,c​。

  可是如何保证不重不漏呢?

  对于 c≠S[i]c \neq S[i]c​=S[i],显然有 fi,c=fi−1,cf_{i,c} = f_{i - 1, c}fi,c​=fi−1,c​,而对于 c=S[i]c = S[i]c=S[i] 的情况,考虑重新统计即 fi,c=∑c′=1c−1fi−1,c′f_{i,c} = \sum_{c'=1}^{c-1}f_{i-1,c'}fi,c​=∑c′=1c−1​fi−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: 咫尺天涯

本题总分:101010 分


【问题描述】

  皮亚诺曲线是一条平面内的曲线。

  下图给出了皮亚诺曲线的 111 阶情形,它是从左下角出发,经过一个 3×33 × 33×3 的方格中的每一个格子,最终到达右上角的一条曲线。

  设每个格子的边长为 111,在上图中,有的相邻的方格(四相邻)在皮亚诺曲线中也是相邻的,在皮亚诺曲线上的距离是 111,有的相邻的方格在皮亚诺曲线中不相邻,距离大于 111。

  例如,正中间方格的上下两格都与它在皮亚诺曲线上相邻,距离为 111,左右两格都与它在皮亚诺曲线上不相邻,距离为 333。

  下图给出了皮亚诺曲线的 222 阶情形,它是经过一个 32×323^2 × 3^232×32 的方格中的每一个格子的一条曲线。它是将 111 阶曲线的每个方格由 111 阶曲线替换而成。

  下图给出了皮亚诺曲线的 333 阶情形,它是经过一个 33×333^3 × 3^333×33 的方格中的每一个格子的一条曲线。它是将 222 阶曲线的每个方格由 111 阶曲线替换而成。

  皮亚诺曲线总是从左下角开始出发,最终到达右上角。

  小蓝对于相邻的方格在皮亚诺曲线上的相邻关系很好奇,他想知道相邻的方格在曲线上的距离之和是多少。

  例如,对于 111 阶皮亚诺曲线,距离和是 242424,有 888 对相邻的方格距离为 111,222 对相邻的方格距离为 333,222 对相邻的方格距离为 555。

  再如,对于 222 阶皮亚诺曲线,距离和是 816816816。

  请求出对于 121212 阶皮亚诺曲线,距离和是多少。

  提示:答案不超过 101810^{18}1018。


【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


184731576397539360


动态规划


  首先考虑分形问题,但是 312×3123^{12} × 3^{12}312×312 的曲线中,相邻的格子对有 2×312×(312−1)2 × 3^{12} × (3^{12} - 1)2×312×(312−1) 个,复杂度爆炸。

  于是考虑动态规划,为此需要选择一些合适的属性来表述状态,合适的策略来完成转移。

  容易想到按阶划分,即将一个 kkk 阶的皮亚诺曲线划分为 333^333 个 k−1k - 1k−1 的皮亚诺曲线,而 k−1k - 1k−1 阶曲线内部相邻块的距离不受其余同阶曲线的影响,固有状态 fif_ifi​ 表示 iii 阶皮亚诺曲线的距离合,fi=33fi−1+Iif_i = 3^3f_{i-1} + I_ifi​=33fi−1​+Ii​,IiI_iIi​ 表示 k−1k - 1k−1 阶曲线直接相邻部分的距离合,而这正是下面要着重讨论的部分。

  对于 222 阶皮亚诺曲线,它的 111 阶曲线相邻的块有:


  容易发现,两行或两列之间相邻块的距离是相等的,于是只需讨论出一行一列的距离合的计算方法,将其和乘以 222 即可计算出 I2I_2I2​。

  其实到这一步问题已经得解,因为分形去求解两块之间的距离, O(3n)O(3^n)O(3n) 的复杂度完全可以在短时间内计算出结果。

#include <stdio.h>typedef long long ll;ll ans, tmp, pow[14]{0, 1};ll abs(ll a) { return a > 0 ? a : -a; }ll calc(int k, ll x, ll y) {if (k == 0) return 0;ll offset = x / pow[k] * 3;int flag = offset == 3;offset += flag ? (3 - y / pow[k] - 1) : (y / pow[k]);if ((offset & 1) == 1)x =  pow[k] - x % pow[k] - 1;return flag ? ((offset + 1) * pow[k] * pow[k] - calc(k - 1, x % pow[k], y % pow[k]) - 1) :(offset * pow[k] * pow[k] + calc(k - 1, x % pow[k], y % pow[k])) ;
}int main() {for (int i = 2; i <= 13; i++) pow[i] = pow[i - 1] * 3;for (int i = 1; i <= 12; i++) {tmp = 0;for (int j = 0; j < pow[i + 1]; j++) {tmp += abs(calc(i, j, pow[i]) - calc(i, j, pow[i] - 1));tmp += abs(calc(i, pow[i], j) - calc(i, pow[i] - 1, j));}ans = 9 * ans + 2 * tmp;}printf("%lld", ans);
}

  有关 分形问题。


试题 E: 玩具蛇

本题总分:151515 分


【问题描述】

  小蓝有一条玩具蛇,一共有 161616 节,上面标着数字 111 至 161616。每一节都是一个正方形的形状。相邻的两节可以成直线或者成 90 度角。

  小蓝还有一个 4×44×44×4 的方格盒子,用于存放玩具蛇,盒子的方格上依次标着字母 A\mathrm AA 到 P\mathrm PP 共 161616 个字母。

  小蓝可以折叠自己的玩具蛇放到盒子里面。他发现,有很多种方案可以将玩具蛇放进去。

  下图给出了两种方案:

  请帮小蓝计算一下,总共有多少种不同的方案。如果两个方案中,存在玩具蛇的某一节放在了盒子的不同格子里,则认为是不同的方案。

【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


552


深度优先搜索


  模板题。

#include <stdio.h>const int N = 4, M = 4, target = N * M;int ans, visited[N + 2][M + 2], offset[4][2]{-1, 0, 0, 1, 1, 0, 0, -1};void dfs(int x, int y, int depth) {visited[x][y] = 1;if (depth == target) ++ans;for (int i = 0; i < 4; ++i)if (!visited[x + offset[i][0]][y + offset[i][1]])dfs(x + offset[i][0], y + offset[i][1], depth + 1);visited[x][y] = 0;
}int main() {for (int i = 1; i <= N; ++i) visited[i][0] = visited[i][M + 1] = 1;for (int i = 1; i <= M; ++i) visited[0][i] = visited[N + 1][i] = 1;for (int i = 1; i <= N; ++i)for (int j = 1; j <= M; ++j) dfs(i, j, 1);printf("%d", ans);
}

试题 F: 皮亚诺曲线距离

时间限制: 1.0s1.0\mathrm s1.0s 内存限制: 256.0MB256.0\mathrm{MB}256.0MB 本题总分:151515 分


【问题描述】

  皮亚诺曲线是一条平面内的曲线。

  下图给出了皮亚诺曲线的 111 阶情形,它是从左下角出发,经过一个 3×33 × 33×3 的方格中的每一个格子,最终到达右上角的一条曲线。


  下图给出了皮亚诺曲线的 222 阶情形,它是经过一个 32×323^{2} × 3^{2}32×32 的方格中的每一个格子的一条曲线。它是将 111 阶曲线的每个方格由 111 阶曲线替换而成。


  下图给出了皮亚诺曲线的 333 阶情形,它是经过一个 33×333^{3} × 3^{3}33×33 的方格中的每一个格子的一条曲线。它是将 222 阶曲线的每个方格由 111 阶曲线替换而成。


  皮亚诺曲线总是从左下角开始出发,最终到达右上角。

  我们将这些格子放到坐标系中,对于 k 阶皮亚诺曲线,左下角的坐标是 (000, 000),右上角坐标是 (3k−13^{k} − 13k−1, 3k−13^{k} − 13k−1),右下角坐标是 (3k−13^{k} − 13k−1, 000),左上角坐标是(000, 3k−13^{k} − 13k−1)。

  给定 k 阶皮亚诺曲线上的两个点的坐标,请问这两个点之间,如果沿着皮亚诺曲线走,距离是到少?

【输入格式】

  输入的第一行包含一个正整数 kkk,皮亚诺曲线的阶数。

  第二行包含两个整数 x1x_{1}x1​, y1y_{1}y1​,表示第一个点的坐标。

  第三行包含两个整数 x2x_{2}x2​, y2y_{2}y2​,表示第二个点的坐标。

【输出格式】

  输出一个整数,表示给定的两个点之间的距离。

【样例输入 1】

1
0 0
2 2

【样例输出 1】

8

【样例输入 2】

2
0 2
0 3

【样例输出 2】

13

【评测用例规模与约定】

  对于 30%30\%30% 的评测用例,0≤k≤100 ≤ k ≤ 100≤k≤10。
  对于 50%50\%50% 的评测用例,0≤k≤200 ≤ k ≤ 200≤k≤20。
  对于所有评测用例,0≤k≤100,0≤x1,y1,x2,y2<3k,x1,y1,x2,y2≤10180 ≤ k ≤ 100, 0 ≤ x_{1}, y_{1}, x_{2}, y_{2} < 3^{k},x_{1}, y_{1}, x_{2}, y_{2} ≤ 10^{18}0≤k≤100,0≤x1​,y1​,x2​,y2​<3k,x1​,y1​,x2​,y2​≤1018。数据保证答案不超过 101810^{18}1018。


分形问题


  如 PeanoCurve\mathrm{Peano\ Curve}Peano Curve 这种,以一定规律无限包含自身的图,可以被称为分形图。

  其衍生出的问题,自然是分形问题。

  我们设 calc(x,y)=(0,0)calc(x, \ y) = (0,0)calc(x, y)=(0,0) 到 (x,y)(x,y)(x,y) 的距离,

  显然答案等于 abs(calc(x1,y1)−calc(x2,y2))abs(calc(x_{1}, \ y_{1}) - calc(x_{2}, \ y_{2}))abs(calc(x1​, y1​)−calc(x2​, y2​))。

  不难看出,一个 k+1k+1k+1 阶皮亚诺曲线由 222 种 kkk 阶皮亚诺曲线连接构成,k>0k>0k>0。

  相信大 伙看到这个图就已经知道程序怎么实现了,过。

  其中一种 kkk 阶皮亚诺曲线为另一种的水平翻转,即 yyy 轴坐标取反,而中线这段皮亚诺曲线与其他曲线的区别在于起点与终点相反,我可以计算出其中一种,再用曲线的大小减去它。

  综上我们可以选择一个策略,

  先按离原点的距离将 kkk 阶皮亚诺曲线分成 0∼80 \sim 80∼8 块 k−1k - 1k−1 阶曲线,显然在这个意义上 k−1k-1k−1 阶曲线与 k−1k-1k−1 阶曲线的水平翻转交替出现,如果坐标落在 k−1k-1k−1 阶曲线的水平翻转上,yyy 取其模 3k−13^{k-1}3k−1 的补数。

  再递归计算坐标所在的 k−1k-1k−1 曲线离其原点的距离,如果坐标落在中线上则用 k−1k - 1k−1 阶曲线的长度减去递归计算到的距离,最后加上编号乘以 k−1k - 1k−1 阶曲线的长度,

  就得到了一个点到原点的距离。

  为了避免爆long long,无论 kkk 为多少,我们都至多视其为 383838,因为 338>10183^{38} > 10^{18}338>1018,而 x,yx,yx,y 不会大于 101810^{18}1018,故而无论kkk大于 383838多少,我们都将其视为左下角第一个 383838 阶 PeanoCurve\mathrm{Peano\ Curve}Peano Curve 即可,但即使这样依然可能会爆 long long,故我们选用__int128


  这里提一下关于网络上,在蓝桥杯时使用__int128无法通过编译的论调。

  截止至 202220222022 年 555 月 555 日 23:35:4023:35:4023:35:40,

  “蓝桥杯”练习系统 在 系统介绍 第六条提到:

  6. 比赛环境:使用和软件大赛相同的测试环境进行测试,有效的模拟大赛的评测。

  然后在 编译环境 提到 C/C\mathrm C/\mathrm CC/C++ 的编译环境:

  C\mathrm CC:    gcc (GCC) 4.9.2

  C\mathrm CC++:g++ (GCC) 4.9.2

  而在 GCC 4.6 Release Series 中我们能看到:

  C family

  Support for a new data type __int128 for targets having wide enough machine-mode support.

  爱用不用,反正我用。


#include <stdio.h>int block[3][3]{0, 1, 2, 5, 4, 3, 6, 7, 8};long long x1, y1, x2, y2, pow[38] = {0, 1};__int128 calc(int k, long long x, long long y) {if (k == 0) return 0;__int128 res = block[x / pow[k]][y / pow[k]];if (res & 1) x = pow[k] - x % pow[k] - 1;return res / 3 != 1 ?res * pow[k] * pow[k] + calc(k - 1, x % pow[k], y % pow[k]) :(res + 1) * pow[k] * pow[k] - calc(k - 1, x % pow[k], y % pow[k]) - 1;
}long long abs(long long a) { return a > 0 ? a : -a; }int min(int a, int b) { return a < b ? a : b; }int k;int main() {scanf("%d %lld %lld %lld %lld", &k, &x1, &y1, &x2, &y2);for (int i = 2; i <= 38; ++i) pow[i] = 3 * pow[i - 1];printf("%lld", abs(calc(min(k, 38), x1, y1) - calc(min(k, 38), x2, y2)));
}

试题 G: 出租车

时间限制: 1.0s1.0\mathrm s1.0s 内存限制: 256.0MB256.0\mathrm{MB}256.0MB 本题总分:202020 分


【问题描述】

  小蓝在 LLL 市开出租车。

  LLL 市的规划很规整,所有的路都是正东西向或者正南北向的,道路都可以看成直线段。东西向的道路互相平行,南北向的道路互相平行,任何一条东西向道路垂直于任何一条南北向道路。

  从北到南一共有 nnn 条东西向道路,依次标号为 H1,H2,⋯,HnH_1, H_2,\ \cdots, H_nH1​,H2​, ⋯,Hn​。从西到东一共有 mmm 条南北向的道路,依次标号为 S1,S2,⋯,SmS_1, S_2,\ \cdots, S_mS1​,S2​, ⋯,Sm​。

  每条道路都有足够长,每一条东西向道路和每一条南北向道路都相交,HiH_iHi​ 与 SjS_jSj​ 的交叉路口记为 (i,j)(i, j)(i,j)。

  从 H1H_1H1​ 和 S1S_1S1​ 的交叉路口 (1,1)(1, 1)(1,1) 开始,向南遇到的路口与 (1,1)(1, 1)(1,1) 的距离分别是 h1,h2,⋯,hn−1h_1, h_2,\ \cdots, h_{n−1}h1​,h2​, ⋯,hn−1​,向东遇到路口与 (1,1)(1, 1)(1,1) 的距离分别是 w1,w2,⋯,wm−1w_1, w_2,\ \cdots, w_{m−1}w1​,w2​, ⋯,wm−1​。

  道路的每个路口都有一个红绿灯。

  时刻 000 的时候,南北向绿灯亮,东西向红灯亮,南北向的绿灯会持续一段时间(每个路口不同),然后南北向变成红灯,东西向变成绿灯,持续一段时间后,再变成南北向绿灯,东西向红灯。

  已知路口 (i,j)(i, j)(i,j) 的南北向绿灯每次持续的时间为 gijg_{ij}gij​,东西向的绿灯每次持续的时间为 rijr_{ij}rij​,红绿灯的变换时间忽略。

  当一辆车走到路口时,如果是绿灯,可以直行、左转或右转。如果是红灯,可以右转,不能直行或左转。如果到路口的时候刚好由红灯变为绿灯,则视为看到绿灯,如果刚好由绿灯变为红灯,则视为看到红灯。

  每段道路都是双向道路,道路中间有隔离栏杆,在道路中间不能掉头,只能在红绿灯路口掉头。掉头时不管是红灯还是绿灯都可以直接掉头。掉头的时间可以忽略。

  小蓝时刻 000 从家出发。今天,他接到了 qqq 个预约的订单,他打算按照订单的顺序依次完成这些订单,就回家休息。中途小蓝不准备再拉其他乘客。

  小蓝的家在两个路口的中点,小蓝喜欢用 x1,y1,x2,y2x_1, y_1, x_2, y_2x1​,y1​,x2​,y2​ 来表示自己家的位置,即路口 (x1,y1)(x_1, y_1)(x1​,y1​) 到路口 (x2,y2)(x_2, y_2)(x2​,y2​) 之间的道路中点的右侧,保证两个路口相邻(中间没有其他路口)。请注意当两个路口交换位置时,表达的是路的不同两边,路中间有栏杆,因此这两个位置实际要走比较远才能到达。

  小蓝的订单也是从某两个路口间的中点出发,到某两个路口间的中点结束。小蓝必须按照给定的顺序处理订单,而且一个时刻只能处理一个订单,不能图省时间而同时接两位乘客,也不能插队完成后面的订单。

  小蓝只对 LLL 市比较熟,因此他只会在给定的 nnn 条东西向道路和 mmm 条南北向道路上行驶,而且不会驶出 H1,Hn,S1,SmH_1, H_n, S_1, S_mH1​,Hn​,S1​,Sm​ 这几条道路所确定的矩形区域(可以到边界)。

  小蓝行车速度一直为 111,乘客上下车的时间忽略不计。

  请问,小蓝最早什么时候能完成所有订单回到家。

【输入格式】

  输入第一行包含两个整数 n,mn, mn,m,表示东西向道路的数量和南北向道路的数量。

  第二行包含 n−1n − 1n−1 个整数 h1,h2,⋯,hn−1h_1, h_2,\ \cdots, h_{n−1}h1​,h2​, ⋯,hn−1​。

  第三行包含 m−1m − 1m−1 个整数 w1,w2,⋯,wm−1w_1, w_2,\ \cdots, w_{m−1}w1​,w2​, ⋯,wm−1​。

  接下来 nnn 行,每行 mmm 个整数,描述每个路口南北向绿灯的时间,其中的第 iii 行第 jjj 列表示 gijg_{ij}gij​。

  接下来 nnn 行,每行 mmm 个整数,描述每个路口东西向绿灯的时间,其中的第 iii 行第 jjj 列表示 rijr_{ij}rij​。

  接下来一行包含四个整数 x1,y1,x2,y2x_1, y_1, x_2, y_2x1​,y1​,x2​,y2​,表示小蓝家的位置在路口 (x1,y1)(x_1, y_1)(x1​,y1​) 到路口 (x2,y2)(x_2, y_2)(x2​,y2​) 之间的道路中点的右侧。

  接下来一行包含一个整数 qqq,表示订单数量。

  接下来 qqq 行,每行描述一个订单,其中第 iii 行包含八个整数 xi1,yi1,xi2,yi2,xi3,yi3,xi4,yi4x_{i1}, y_{i1}, x_{i2}, y_{i2}, x_{i3}, y_{i3}, x_{i4}, y_{i4}xi1​,yi1​,xi2​,yi2​,xi3​,yi3​,xi4​,yi4​,表示第 iii 个订单的起点为路口 (xi1,yi1)(x_{i1}, y_{i1})(xi1​,yi1​) 到路口 (xi2,yi2)(x_{i2}, y_{i2})(xi2​,yi2​) 之间的道路中点的右侧,第 iii 个订单的终点为路口 (xi3,yi3)(x_{i3}, y_{i3})(xi3​,yi3​) 到路口 (xi4,yi4)(x_{i4}, y_{i4})(xi4​,yi4​) 之间的道路中点的右侧。

【输出格式】

  输出一个实数,表示小蓝完成所有订单最后回到家的最早时刻。四舍五入保留一位小数。

【样例输入】

2 3
200
100 400
10 20 10
20 40 30
20 20 20
20 20 20
2 1 1 1
1
2 2 1 2 1 2 1 3

【样例输出】

1620.0

【样例说明】
  小蓝有一个订单,他的行车路线如下图所示。其中 HHH 表示他家的位置,SSS 表示订单的起点,TTT 表示订单的终点。小明在最后回家时要在直行的红绿灯路口等绿灯,等待时间为 202020。

【评测用例规模与约定】

  对于 20%20\%20% 的评测用例,1≤n,m≤5,1≤q≤101 ≤ n, m ≤ 5,1 ≤ q ≤ 101≤n,m≤5,1≤q≤10。
  对于 50%50\%50% 的评测用例,1≤n,m≤30,1≤q≤301 ≤ n, m ≤ 30,1 ≤ q ≤ 301≤n,m≤30,1≤q≤30。
  对于所有评测用例,1≤n,m≤100,1≤q≤30,1≤h1<h2<⋯<hn−1≤100000,1≤w1<w2<⋯<wm−1≤100000,1≤gij≤1000,1≤rij≤10001 ≤ n, m ≤ 100,1 ≤ q ≤ 30,1 ≤ h_1 < h_2 <\ \cdots< h_{n−1} ≤ 100000,1 ≤ w_1 < w_2 <\ \cdots< w_{m−1} ≤ 100000,1 ≤ g_{ij} ≤ 1000,1 ≤ r_{ij} ≤ 10001≤n,m≤100,1≤q≤30,1≤h1​<h2​< ⋯<hn−1​≤100000,1≤w1​<w2​< ⋯<wm−1​≤100000,1≤gij​≤1000,1≤rij​≤1000,给定的路口一定合法。


// 大模拟,没有写的意义。

试题 H: 答疑

时间限制: 1.0s1.0\mathrm s1.0s 内存限制: 256.0MB256.0\mathrm{MB}256.0MB 本题总分:202020 分


【问题描述】

  有 nnn 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。

  老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。

  一位同学答疑的过程如下:

  1. 首先进入办公室,编号为 iii 的同学需要 sis_{i}si​ 毫秒的时间。

  2. 然后同学问问题老师解答,编号为 iii 的同学需要 aia_{i}ai​ 毫秒的时间。

  3. 答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可以忽略。

  4. 最后同学收拾东西离开办公室,需要 eie_{i}ei​ 毫秒的时间。一般需要 101010 秒、202020 秒或 303030 秒,即 eie_{i}ei​ 取值为 100001000010000,200002000020000 或 300003000030000。

  一位同学离开办公室后,紧接着下一位同学就可以进入办公室了。

  答疑从 000 时刻开始。老师想合理的安排答疑的顺序,使得同学们在课程群里面发消息的时刻之和最小。

【输入格式】

  输入第一行包含一个整数 nnn,表示同学的数量。

  接下来 nnn 行,描述每位同学的时间。其中第 iii 行包含三个整数 sis_{i}si​, aia_{i}ai​, eie_{i}ei​,意义如上所述。

【输出格式】

  输出一个整数,表示同学们在课程群里面发消息的时刻之和最小是多少。

【样例输入】

3
10000 10000 10000
20000 50000 20000
30000 20000 30000

【样例输出】

280000

【样例说明】
  按照 1,3,21, 3, 21,3,2 的顺序答疑,发消息的时间分别是 20000,80000,18000020000, 80000, 18000020000,80000,180000。

【评测用例规模与约定】

  对于 30%30\%30% 的评测用例,1≤n≤201 ≤ n ≤ 201≤n≤20。
  对于 60%60\%60% 的评测用例,1≤n≤2001 ≤ n ≤ 2001≤n≤200。
  对于所有评测用例,1≤n≤10001 ≤ n ≤ 10001≤n≤1000,1≤si≤600001 ≤ s_i ≤ 600001≤si​≤60000,1≤ai≤10000001 ≤ a_i ≤ 10000001≤ai​≤1000000,ei∈{10000,20000,30000}e_i\in\{10000,20000,30000\}ei​∈{10000,20000,30000},即 eie_iei​ 一定是 10000、20000、3000010000、20000、3000010000、20000、30000 之一。


贪心


  第 iii 个同学在第 i′i'i′ 位被答疑,在课程群里面发消息的时刻为:

  ∑j′=1i′(sj′+aj′+ej′)−ei′\displaystyle{\sum_{j'=1}^{i'}}(s_{j'}+a_{j'}+e_{j'})-e_{i'}j′=1∑i′​(sj′​+aj′​+ej′​)−ei′​

  故同学们在课程群里面发消息的时刻之和为:

  ∑i′=1n∑j′=1i′(sj′+aj′+ej′)−∑i′=1nei′\displaystyle{\sum_{i'=1}^n\sum_{j'=1}^{i'}}(s_{j'}+a_{j'}+e_{j'})-\sum_{i'=1}^ne_{i'}i′=1∑n​j′=1∑i′​(sj′​+aj′​+ej′​)−i′=1∑n​ei′​

  设 Bi=si+ai+eiB_i = s_i + a_i + e_iBi​=si​+ai​+ei​,考虑答疑顺序按 BiB_iBi​ 降序排序,可以发现对于任意 i′,j′i',j'i′,j′,Bi≠BjB_i \neq B_jBi​​=Bj​,交换都会使答案增加 (j′−i′)(Bj−Bi)(j' -i')(B_j-B_i)(j′−i′)(Bj​−Bi​),故上述次序是一个最优解。

#include <stdio.h>
#include <algorithm>int n, s, a, e, B[1001];long long ans, sum;bool cmp(int a, int b) { return a > b; }int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i)scanf("%d %d %d", &s, &a, &e),ans -= e, B[i] = s + a + e;std::sort(B + 1, B + n + 1, cmp);for (int i = 1; i <= n; ++i)sum += B[i], ans += i * B[i];printf("%lld", ans);
}

试题  I: 奇偶覆盖

时间限制: 1.0s1.0\mathrm s1.0s 内存限制: 256.0MB256.0\mathrm{MB}256.0MB 本题总分:252525 分


【问题描述】

  在平面内有一些矩形,它们的两条边都平行于坐标轴。

  我们称一个点被某个矩形覆盖,是指这个点在矩形的内部或者边界上。

  请问,被奇数个矩形覆盖和被偶数 (≥2)(≥ 2)(≥2) 个矩形覆盖的点的面积分别是多少?

【输入格式】

  输入的第一行包含一个整数 nnn,表示矩形的个数。

  接下来 nnn 行描述这些矩形,其中第 iii 行包含四个整数 li,bi,ri,til_i,b_i, r_i, t_ili​,bi​,ri​,ti​ ,表示矩形的两个对角坐标分别为 (li,bi),(ri,ti)(l_i, b_i),(r_i, t_i)(li​,bi​),(ri​,ti​)。

【输出格式】

  输出两行。
  第一行包含一个整数,表示被奇数个矩形覆盖的点的面积。
  第二行包含一个整数,表示被偶数 (≥2)(≥ 2)(≥2) 个矩形覆盖的点的面积。

【样例输入】

3
1 1 3 3
2 2 4 4
3 3 5 5

【样例输出】

8
2

【评测用例规模与约定】

  对于 202020% 的评测用例,1≤n≤10,0≤li<ri≤100,0≤bi<ti≤1001 ≤ n ≤ 10, 0 ≤ l_i < r_i ≤ 100, 0 ≤ b_i < t_i ≤ 1001≤n≤10,0≤li​<ri​≤100,0≤bi​<ti​≤100。
  对于 404040% 的评测用例,1≤n≤1000,0≤li<ri≤100,0≤bi<ti≤1001 ≤ n ≤ 1000, 0 ≤ l_i < r_i ≤ 100, 0 ≤ b_i < t_i ≤ 1001≤n≤1000,0≤li​<ri​≤100,0≤bi​<ti​≤100。
  对于 606060% 的评测用例,1≤n≤10000,0≤li<ri≤1000,0≤bi<ti≤10001 ≤ n ≤ 10000, 0 ≤ l_i < r_i ≤ 1000, 0 ≤ b_i < t_i ≤ 10001≤n≤10000,0≤li​<ri​≤1000,0≤bi​<ti​≤1000。
  对于 808080% 的评测用例,1≤n≤100000,0≤li<ri≤100000,0≤bi<ti≤1000001 ≤ n ≤ 100000, 0 ≤ l_i < r_i ≤ 100000, 0 ≤ b_i < t_i ≤ 1000001≤n≤100000,0≤li​<ri​≤100000,0≤bi​<ti​≤100000。
  对于所有评测用例,1≤n≤100000,0≤li<ri≤109,0≤bi<ti≤1091 ≤ n ≤ 100000, 0 ≤ l_i < r_i ≤ 10^9, 0 ≤ b_i < t_i ≤ 10^91≤n≤100000,0≤li​<ri​≤109,0≤bi​<ti​≤109。


扫描线


  写完就后悔了,一般扫描线有两种写法,一种是将子区间二进制拆分建线段树,在这道题里最少要开 nnn 的 888 倍内存,另一种则是端点表示法,[l,r][l,r][l,r] 表示 [l,r+1][l,r+1][l,r+1] 间的信息,在这道题里值要开 nnn 的 444 倍内存,

  但我写都写了,过,下一道。

#include <stdio.h>
#include <algorithm>const int N = 100009;long long oddc, evenc;int S[N << 1], L[N << 4], R[N << 4], length[N << 4], odd[N << 4], even[N << 4], cover[N << 4];void build(int rt, int l, int r) {L[rt] = S[l], R[rt] = S[r], length[rt] = S[r] - S[l];if (r - l > 1) {build(rt << 1, l, l + r >> 1);build(rt << 1 | 1, l + r >> 1, r);}
}void push_up(int rt) {odd[rt] = odd[rt << 1] + odd[rt << 1 | 1];even[rt] = even[rt << 1] + even[rt << 1 | 1];if (cover[rt])if (cover[rt] & 1)std::swap(odd[rt], even[rt]), odd[rt] = length[rt] - even[rt];elseeven[rt] = length[rt] - odd[rt];
}void update(int rt, int l, int r, int k) {if (l >= r) return;if (L[rt] == l && R[rt] == r) cover[rt] += k;else {if (l <= R[rt << 1])update(rt << 1, l, std::min(r, R[rt << 1]), k);if (r >= L[rt << 1 | 1])update(rt << 1 | 1, std::max(l, L[rt << 1 | 1]), r, k);}push_up(rt);
}struct line {int x1, x2, y, flag;inline bool operator<(const line &l) const { return y < l.y; }
} lines[N << 1];int n, l, b, r, t;int main() {scanf("%d", &n);for (int i = 0; i < n; ++i) {scanf("%d %d %d %d", &l, &b, &r, &t);lines[i] = {l, r, b,  1};lines[i + n] = {l, r, t, -1};S[i] = l, S[i + n] = r;}std::sort(S, S + 2 * n);std::sort(lines, lines + 2 * n);build(1, 0, std::unique(S, S + 2 * n) - S - 1);update(1, lines->x1, lines->x2, 1);for (int i = 1; i < 2 * n; ++i) {oddc += (long long)(lines[i].y - lines[i - 1].y) * odd[1];evenc += (long long)(lines[i].y - lines[i - 1].y) * even[1];update(1, lines[i].x1, lines[i].x2, lines[i].flag);}printf("%lld\n%lld", oddc, evenc);
}

试题 J: 蓝跳跳

时间限制: 2.0s2.0\mathrm s2.0s 内存限制: 256.0MB256.0\mathrm{MB}256.0MB 本题总分:252525 分


【问题描述】

  小蓝制作了一个机器人,取名为蓝跳跳,因为这个机器人走路的时候基本靠跳跃。

  蓝跳跳可以跳着走,也可以掉头。蓝跳跳每步跳的距离都必须是整数,每步可以跳不超过 kkk 的长度。由于蓝跳跳的平衡性设计得不太好,如果连续两次都是跳跃,而且两次跳跃的距离都至少是 ppp,则蓝跳跳会摔倒,这是小蓝不愿意看到的。

  小蓝接到一个特别的任务,要在一个长为 LLL 舞台上展示蓝跳跳。小蓝要控制蓝跳跳从舞台的左边走到右边,然后掉头,然后从右边走到左边,然后掉头,然后再从左边走到右边,然后掉头,再从右边走到左边,然后掉头,如此往复。

  为了让观者不至于太无趣,小蓝决定让蓝跳跳每次用不同的方式来走。小蓝将蓝跳跳每一步跳的距离记录下来,按顺序排成一列,显然这一列数每个都不超过 kkk 且和是 LLL。这样走一趟就会出来一列数。如果两列数的长度不同,或者两列数中存在一个位置数值不同,就认为是不同的方案。

  请问蓝跳跳在不摔倒的前提下,有多少种不同的方案从舞台一边走到另一边。

【输入格式】

  输入一行包含三个整数 k,p,Lk, p, Lk,p,L。

【输出格式】

  输出一个整数,表示答案。答案可能很大,请输出答案除以 202011142020111420201114 的余数。

【样例输入 1】

3 2 5

【样例输出 1】

9

【样例输入 2】

5 3 10

【样例输出 2】

397

【样例说明】
  对于样例输入 1,蓝跳跳有以下 9 种跳法:
 1. 1+1+1+1+1
 2. 1+1+1+2
 3. 1+1+2+1
 4. 1+2+1+1
 5. 2+1+1+1
 6. 2+1+2
 7. 1+1+3
 8. 1+3+1
 9. 3+1+1

【评测用例规模与约定】

  对于 30%30\%30% 的评测用例,1≤p≤k≤50,1≤L≤10001 ≤ p ≤ k ≤ 50, 1 ≤ L ≤ 10001≤p≤k≤50,1≤L≤1000。
  对于 60%60\%60% 的评测用例,1≤p≤k≤50,1≤L≤1091 ≤ p ≤ k ≤ 50, 1 ≤ L ≤ 10^91≤p≤k≤50,1≤L≤109。
  对于 80%80\%80% 的评测用例,1≤p≤k≤200,1≤L≤10181 ≤ p ≤ k ≤ 200, 1 ≤ L ≤ 10^{18}1≤p≤k≤200,1≤L≤1018。
  对于所有评测用例,1≤p≤k≤1000,1≤L≤10181 ≤ p ≤ k ≤ 1000, 1 ≤ L ≤ 10^{18}1≤p≤k≤1000,1≤L≤1018。


不会


  又对着这题自闭一下午。

第十一届蓝桥杯大赛软件类决赛(C/C++ 大学A组)相关推荐

  1. 2022年第十三届蓝桥杯大赛软件类决赛C/C++大学B组C题卡牌

    题意: 有n种牌,第i种牌有ai 张,一套牌为n张牌每种各一张,为凑出更多的牌,用m张空白牌写上种类,每种最多写bi张,求最多能凑几幅牌. 思考: 已知ai.bi,不考虑有多少张空白牌,最多能凑min ...

  2. 2022年第十三届蓝桥杯大赛软件类决赛C/C++大学B组(国赛)题解

    2022国赛B组 题目一:C题 卡牌 题目二:D题 最大数字 题目三:E题 出差 题目四:F题 费用报销 题目五:G题 故障 题目六:H题 机房 题目七:I题 齿轮 题目八:J题 搬砖 刷题链接: h ...

  3. 2022年第十三届蓝桥杯大赛软件类决赛C/C++大学B组E题出差

    题意: 有N个城市,编号1...N,无法从1出发到N,需要通过其他城市中转,并且到达后需隔离,求1到N时间最短的路线. 思路: 最短路变形,求时间最短,使用Dijkstra算法松弛时需加上隔离的时间, ...

  4. 第十一届蓝桥杯大赛软件类决赛(2020javaB国赛)

    第十一届蓝桥杯大赛软件类决赛 Java 大 学 B 组 目录 第十一届蓝桥杯大赛软件类决赛 试题 A: 美丽的 2 试题 B: 扩散 试题 C: 阶乘约数 试题 D: 本质上升序列 试题 E: 玩具蛇 ...

  5. 第十一届蓝桥杯大赛软件类决赛 C++ B组 题解

    声明:本人水平有限,只是个人的见解,如果有更好的答案,欢迎评论区或者私信我,我会注明您的题解来源,谢谢支持! 本文是2020年11月14日的蓝桥杯全国总决赛  软件类 C B组题解 本文原创首发CSD ...

  6. 第十三届蓝桥杯大赛软件赛决赛(Java 大学B组)

    蓝桥杯 2022年国赛真题 Java 大学B组  试题 A: 重合次数  试题 B: 数数  试题 C: 左移右移  试题 D: 窗口  试题 E: 迷宫  试题 F: 小球称重  试题 G: 背包与 ...

  7. 第十三届蓝桥杯大赛软件赛决赛(Java 大学C组)

    蓝桥杯 2022年国赛真题 Java 大学C组 试题 A: 斐波那契与 7 试题 B: 小蓝做实验 试题 C: 取模 试题 D: 内存空间 试题 E: 斐波那契数组 试题 F: 最大公约数 试题 G: ...

  8. 第十三届蓝桥杯大赛软件赛决赛(Java 大学A组)

    蓝桥杯 2022年国赛真题 Java 大学A组 试题 A: 火柴棒数字 试题 B: 小蓝与钥匙 试题 C: 内存空间 试题 D: 斐波那契数组 试题 E: 交通信号 试题 F: 数组个数 试题 G: ...

  9. 第十一届蓝桥杯大赛软件类决赛 Python大学组

    填空(答案已测试) 试题A:美丽的2(5) 暴力,for一遍就行了 count=0 for i in range(1,2021):if "2" in str(i):count+=1 ...

最新文章

  1. Boost 1.53.0 发布,可移植的C++标准库
  2. Android定位方式和测试方法
  3. 赠书 | 干货!用 Python 动手学强化学习
  4. 谷歌正式开源Model Search!自动优化并识别AI模型,最佳模版唾手可得
  5. 面向对象编程思想(2)--策略模式
  6. Windows Home Server中文版使用全攻略
  7. RuntimeError: inconsistent AsyncHTTPClient cache
  8. 谈谈登录密码传输这件小事
  9. MySQL分区表概述
  10. laravel的foreach
  11. 数据库零碎要点002---认识时序数据库
  12. 使用Python成功调用大漠插件方法
  13. 微信小程序demo、开发工具下载地址
  14. 计算机策略组无法打开怎么办,Win10系统gpedit.msc组策略打不开怎么解决
  15. 华为组织结构30年演变历程(一文说透)
  16. 内是独体字还是半包围_独体字与半包围的字究竟怎么区分?
  17. blastn 输出结果每列啥意思_如何看懂NCBI BLAST输出结果
  18. [洛谷P3527] [POI2011]MET-Meteors
  19. 中国用于先天性代谢错误的医用食品市场深度研究分析报告
  20. 幸运数划分 lucky

热门文章

  1. 万万没想到,“红孩儿”竟然做了程序员,还是CTO!
  2. 禅道 mysql 错误
  3. Python基础:68 个 Python 内置函数详解
  4. 标准身材计算机法,计算机(程序)基础_堂堂5尺爷们不到100斤_数之美
  5. Android中MVC,MVP和MVVM的区别
  6. 给windows7系统盘瘦身
  7. Oracle Database XE(免费)的数据库下载安装使用教程-第一篇
  8. 斯皮尔曼相关系数范围_Spearman Rank(斯皮尔曼等级)相关系数及MATLAB实现
  9. 《平衡掌控者 游戏数值战斗设计》学习笔记(三)战斗公式
  10. ESP8266-SPI通讯连接显示屏