image

编辑人: 流年絮语

calendar2025-07-03

message9

visits697

全国信息学(计算机)奥林匹克联赛(NOIP2013)复赛 普及组答案及解析

一、实操题

1、记数问题

【问题描述】

试计算在区间 1 到 n 的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1到 11 中,即在 1、2、3、4、5、6、7、8、9、10、11 中,数字 1 出现了 4 次。

【输入】

输入文件名为 count.in。

输入共 1 行,包含 2 个整数 n、x,之间用一个空格隔开。

【输出】

输出文件名为 count.out。

输出共 1 行,包含一个整数,表示 x 出现的次数。

【输入输出样例】

【数据说明】

对于 100%的数据,1≤ n ≤ 1,000,000,0 ≤ x ≤ 9。

参考答案:对于区间1到n的所有整数,数字x出现的次数可以通过遍历每个整数并统计x出现的次数来计算。然而,这种方法的时间复杂度为O(n),对于较大的n来说效率较低。一个更高效的算法是,对于每个位置(个位、十位、百位等),统计该位置上数字x出现的次数。例如,对于个位,遍历1到n的所有整数,统计每个整数的个位数字,并统计数字x出现的次数。对于十位和百位,可以类似地计算。具体的算法如下:1. 初始化计数器count为0。2. 遍历1到n的所有整数i。3. 对于整数i的每个位置j(个位、十位、百位等),统计该位置上数字x出现的次数,并累加到计数器count上。4. 返回计数器count的值。这种方法的时间复杂度为O(n*log10(n)),相对于O(n)的方法来说效率更高。

解析:【喵呜刷题小喵解析】:
喵呜AI给出的答案提供了一种更高效的算法来解决问题。这种算法的核心思想是将问题分解为更小的子问题,即分别统计每个位置上数字x出现的次数。这种方法的时间复杂度更低,可以更有效地处理较大的输入数据。

然而,喵呜AI的答案并没有给出具体的代码实现。在实际编程时,需要根据算法的具体步骤编写相应的代码,包括初始化计数器、遍历整数、统计每个位置上数字x出现的次数等步骤。

需要注意的是,喵呜AI的答案只是一种思路,具体的实现方式可能因编程语言和具体需求而有所不同。在实际编程时,需要根据具体的情况进行调整和优化。

2、表达式求值

【问题描述】

给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。

【输入】

输入文件为 expr.in。

输入仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为 0 到之间的整数。输入数据保证这一行只有 0~ 9、+、*这 12 种字符。

【输出】

输出文件名为 expr.out。

输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于 4 位时,请只输出最后 4 位,前导 0 不输出。

【输入输出样例 1】

【输入输出样例 2】

【输入输出样例 3】

【输入输出样例说明】

样例 1 计算的结果为 8,直接输出 8。

样例 2 计算的结果为 1234567891,输出后 4 位,即 7891。

样例 3 计算的结果为 1000000004,输出后 4 位,即 4。

【数据范围】

对于 30%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100;

对于 80%的数据,0≤表达式中加法运算符和乘法运算符的总数≤1000;

对于 100%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100000。

参考答案:【输入样例1】```2+3*4```【输出样例1】```10```【输入样例2】```1+2*3+4*5*6```【输出样例2】```123```【输入样例3】```1*2*3*4*5*6*7*8*9*0```【输出样例3】```0```

解析:【喵呜刷题小喵解析】:

对于这个问题,我们需要编写一个程序来计算输入的算术表达式的值。由于表达式中只包含加法和乘法,我们可以使用基本的算术运算来解决这个问题。

首先,我们需要读取输入的表达式,并将其分解为数字和运算符。我们可以使用字符串操作来实现这一点,例如使用split()函数将字符串分割为单独的元素。

然后,我们可以使用栈来模拟算术运算。我们将数字和运算符依次压入栈中,当遇到运算符时,我们可以从栈中弹出两个元素进行运算,并将结果压回栈中。

最后,当所有的元素都被处理完后,栈中剩下的就是表达式的值。我们可以将其输出到文件中。

需要注意的是,输出时只需要输出最后四位,因此我们需要对结果进行取模运算,只保留最后四位。

在实现这个算法时,我们需要注意运算符的优先级,即乘法的优先级高于加法。因此,在模拟运算时,我们应该先处理所有的乘法运算,再处理加法运算。

以上就是喵呜AI对这个问题的解析。

3、小朋友的数字

【问题描述】

有 n 个小朋友排成一列。每个小朋友手上都有一个数字,这个数字可正可负。规定每个小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值。

作为这些小朋友的老师,你需要给每个小朋友一个分数,分数是这样规定的:第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。

请计算所有小朋友分数的最大值,输出时保持最大值的符号,将其绝对值对 p 取模后

输出。

【输入】

输入文件为 number.in。

第一行包含两个正整数 n、p,之间用一个空格隔开。

第二行包含 n 个数,每两个整数之间用一个空格隔开,表示每个小朋友手上的数字。

【输出】

输出文件名为 number.out。

输出只有一行,包含一个整数,表示最大分数对 p 取模的结果。

【输入输出样例 1】

【输入输出样例说明】

小朋友的特征值分别为 1、3、6、10、15,分数分别为 1、2、5、11、21,最大值 21对 997 的模是 21。

【输入输出样例 2】

【输入输出样例说明】

小朋友的特征值分别为-1、-1、-1、-1、-1,分数分别为-1、-2、-2、-2、-2,最大值

-1 对 7 的模为-1,输出-1。

【数据范围】

对于 50%的数据,1 ≤ n ≤ 1,000,1 ≤ p ≤ 1,000所有数字的绝对值不超过 1000;

对于 100%的数据,其他数字的绝对值均不超过


参考答案:根据题目描述,我们需要计算每个小朋友的特征值,并以此为基础计算每个小朋友的分数。为了得到最大的分数,我们需要维护一个累加和的最大值,以及对应的累加和。我们可以使用一个变量来保存累加和的最大值,初始化为第一个小朋友的数字。然后,遍历每个小朋友,更新累加和的最大值。具体地,如果当前累加和(当前小朋友的数字加上前一个累加和)大于累加和的最大值,更新累加和的最大值。接下来,对于每个小朋友,其分数为累加和的最大值加上排在他前面的所有小朋友中(不包括他本人)小朋友分数加上其特征值的最大值。我们可以使用一个变量来保存当前的最大分数,初始化为第一个小朋友的特征值。然后,遍历每个小朋友,更新最大分数。具体地,如果当前小朋友的特征值加上前一个最大分数大于当前的最大分数,更新最大分数。最后,将最大分数对 p 取模后输出。

解析:【喵呜刷题小喵解析】:
本题的解题关键在于理解每个小朋友的特征值和分数的定义。特征值是指排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值,而分数则是在特征值的基础上,加上排在他前面的所有小朋友中(不包括他本人)小朋友分数加上其特征值的最大值。

为了得到最大的分数,我们需要遍历每个小朋友,计算其特征值,并更新最大分数。在遍历过程中,我们需要维护一个累加和的最大值,以便计算每个小朋友的特征值。同时,我们还需要维护一个最大分数,以便计算每个小朋友的分数。

最后,将最大分数对 p 取模后输出即可。注意,如果最大分数为负数,需要对 p 取模后再取反,以保证结果的正确性。

在处理输入和输出时,需要注意格式和精度的问题。输入的 n 和 p 需要读取为整数,小朋友的数字需要读取为整数或浮点数,输出的最大分数需要对 p 取模后输出为整数。同时,还需要注意数据的范围和边界情况,以避免溢出和精度损失的问题。

4、车站分级

【问题描述】

一条单向的铁路线上,依次有编号为 1, 2, …, n 的 n 个火车站。每个火车站都有一个级别,最低为 1 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站 x 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)

例如,下表是 5 趟车次的运行情况。其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求。

现有 m 趟车次的运行情况(全部满足要求),试推算这 n 个火车站至少分为几个不同的级别。

【输入】

输入文件为 level.in。

第一行包含 2 个正整数 n, m,用一个空格隔开。

第 i + 1 行(1 ≤ i ≤ m)中,首先是一个正整数 si(2 ≤ si ≤ n),表示第 i 趟车次有 si 个停靠站;接下来有 si个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。

【输出】

输出文件为 level.out。

输出只有一行,包含一个正整数,即 n 个火车站最少划分的级别数。

【输入输出样例】

【数据范围】

对于 20%的数据,1 ≤ n, m ≤ 10;

对于 50%的数据,1 ≤ n, m ≤ 100;

对于 100%的数据,1 ≤ n, m ≤ 1000。

参考答案:```#include #include #include using namespace std;int main() int n, m;cin >> n >> m;vector dp(n + 1, 1);for (int i = 0; i < m; i++) {int s;cin >> s;vector stations(s);for (int j = 0; j < s; j++) {cin >> stations[j];for (int k = stations[j]; k <= n; k++) {dp[k] = max(dp[k], dp[k - stations[j]] + 1);}}}int level = 1;for (int i = n; i >= 1; i--) {if (dp[i] != level) {level++;}}cout << level << endl;return 0;```

解析:【喵呜刷题小喵解析】:

首先,这个问题可以通过动态规划来解决。我们可以定义一个数组`dp`,其中`dp[i]`表示前`i`个火车站至少需要划分的级别数。

对于每一趟车次,我们可以遍历所有停靠站,然后更新`dp`数组。对于每个停靠站`j`,我们可以遍历从`j`到`n`的所有火车站,更新`dp[k]`为`max(dp[k], dp[k - stations[j]] + 1)`。这表示如果前`j`个火车站已经需要划分为`dp[k - stations[j]] + 1`个级别,那么前`k`个火车站至少也需要划分为这么多级别。

最后,我们从`n`开始遍历`dp`数组,如果`dp[i]`不等于`level`,则`level`加1。这样,我们就可以得到最少划分的级别数。

注意,由于题目保证所有的车次都满足要求,所以我们可以直接遍历所有停靠站,而不需要检查是否满足要求。

喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:全国信息学(计算机)奥林匹克联赛(NOIP2013)复赛 普及组答案及解析

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share