PDF文档公众号回复关键字:20240729
2020 CSP-J 阅读程序3
1阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 √,错误填 ×。除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分)
01 #include <algorithm>
02 #include <iostream>
03 using namespace std;
04
05 int n;
06 int d[50][2];
07 int ans;
08
09 void dfs(int n, int sum) {
10 if (n == 1) {
11 ans = max(sum, ans);
12 return;
13 }
14 for (int i = 1; i < n; ++i) {
15 int a = d[i - 1][0], b = d[i - 1][1];
16 int x = d[i][0], y = d[i][1];
17 d[i - 1][0] = a + x;
18 d[i - 1][1] = b + y;
19 for (int j = i; j < n - 1; ++j)
20 d[j][0] = d[j + 1][0], d[j][1] = d[j + 1][1];
21 int s = a + x + abs(b - y);
22 dfs(n - 1, sum + s);
23 for (int j = n - 1; j > i; --j)
24 d[j][0] = d[j - 1][0], d[j][1] = d[j - 1][1];
25 d[i - 1][0] = a, d[i - 1][1] = b;
26 d[i][0] = x, d[i][1] = y;
27 }
28 }
29
30 int main() {
31 cin >> n;
32 for (int i = 0; i < n; ++i)
33 cin >> d[i][0];
34 for (int i = 0; i < n;++i)
35 cin >> d[i][1];
36 ans = 0;
37 dfs(n, 0);
38 cout << ans << endl;
39 return 0;
40 }
假设输入的n是不超过50的正整数,d[i] [0]、d[i] [i]都是不超过10000的正整数,
完成下面的判断题和单选题
28.若输入 n 为 0,此程序可能会死循环或发生运行错误( )[1.5分]
29.若输入 n 为 20,接下来的输入全为 0,则输出为 0 ( )[1.5分]
30.输出的数一定不小于输入的 d[i] [0] 和 d[i] [1] 的任意一个( )[1.5分]
31.若输入的 n 为 20,接下来的输入是 20 个 9 和 20 个 0,则输出为( )[3分]
A.1890
B.1881
C.1908
D.1917
32.若输入的 n 为 30,接下来的输入是 30 个 0 和 30 个 5,则输出为( )[3分]
A.2000
B.2010
C.2030
D.2020
33.若输入的 n 为 15,接下来的输入是 15 到 1,以及 15到1,则输出为( )[4分]
A.2440
B.2220
C.2240
D.2420
2 相关知识点
1) 平方和公式
平方和公式
平方和公式是一个比较常用公式,用于求连续自然数的平方和(Sum of squares)
从1开始的连续自然数平方和公式
1^2+2^2+3^2+…+n^2=n(n+1)(2n+1)/6
例如
1^2+2^2+3^2+4^2+5^2+6^2=(6*7*13)/6=91
2) 等差数列求和
等差数列求和公式
sn=(a1+an)∗n/2
其中a1是第1项,an是第n项,n是总共n个数求和
例如
1+2+3+4+5+6=(1+6)*6/2=21
2+4+6+8+10=(2+10)*5/2=30
3) 求和扩展C++
1×2+2×3+3×4+…+99×100
= 1×(1+1)+2×(2+1)+3×(3+1)+...+98×(98+1)+99×(99+1)
= 1^2+1 + 2^2+2 +3^2+3 +...+98^3+98 +99^2+99
= (1^2 + 2^2 +3^2 +... 98^2 + 99^2) + (1 + 2 +3 +... 98 + 99) --前半部分适用平方和公式 、后半部分适用等差数列求和
=99*(99+1)*(2*99+1)/6 + (1+99)*99/2
=328350+4950
=333300
4) 深度优先搜索DFS
深度优先搜索
深度优先搜索是一种递归的搜索算法。它从起始节点开始,递归地访问每一个节点,直到找到目标节点或者搜索完整张图
5) 搜索与回溯
是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。
回溯是搜索算法中的一种控制策略。
它的基本思想是:为了求得问题的解,先选择某一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前探索,如此反复进行,直至得到解或证明无解
3 思路分析
假设输入的n是不超过50的正整数,d[i] [0]、d[i] [i]都是不超过10000的正整数,
完成下面的判断题和单选题
28.若输入 n 为 0,此程序可能会死循环或发生运行错误( F )[1.5分]
分析
n为0时,第10行退出条件判断不满足条件,不会进入
第14行循环不会进入,程序直接结束,不会出现死循环和发送运行错误
29.若输入 n 为 20,接下来的输入全为 0,则输出为 0 ( T )[1.5分]
分析
此程序主要逻辑是,计算第0列合并后的最大值及其第1列合并后相减绝对值的最大值
输入都是0,没次合并后计算结果都是0,则输出0
30.输出的数一定不小于输入的 d[i] [0] 和 d[i] [1] 的任意一个( F )[1.5分]
分析
可以找出反例
输入n=1时,无论d[i][0]=4和d[i][1]=2 时,输出为0
因为无法进入第10行和第14行,不会改变ans的初始值
31.若输入的 n 为 20,接下来的输入是 20 个 9 和 20 个 0,则输出为( B )[3分]
A.1890
B.1881
C.1908
D.1917
分析
输入20个9和20个0,由于20个0,对第1列合并总是0,所以可以忽略
运用贪心的思想发现,每次让刚刚合并过的行,参与下一次合并,得到的sum最大
所以sum累加为
(9+9)+(9+9+9)+(9+9+9+9)+...(9*20) --根据等差数列求和 sn=(a1+an)∗n/2
=(18+180)*19/2
=1881
32.若输入的 n 为 30,接下来的输入是 30 个 0 和 30 个 5,则输出为( C )[3分]
A.2000
B.2010
C.2030
D.2020
分析
输入30个0和30个5,由于30个0,对第0列合并总是0,所以可以忽略
运用贪心的思想发现,每次让刚刚合并过的行,参与下一次合并,得到的sum最大
0+5+5*2+5*3+5*28 --根据等差数列求和 sn=(a1+an)∗n/2
=(0+28*5)*28/2
=2030
33.若输入的 n 为 15,接下来的输入是 15 到 1,以及 15到1,则输出为( C )[4分]
A.2440
B.2220
C.2240
D.2420
分析
输入n为15 15个15到1和15个15到1
运用贪心的思想发现,用最大的参与合并,每次让刚刚合并过的行,参与下一次合并,得到的sum最大
计算a+x,其中每个数合并的次数,从较大的数开始
15第1个参与运算15累加了14次
14第2个参与运算14累加了13次
...
2第14次参与运算2累加了1次
每1行合并时,x的值
第1次 x为14
第2次 x为13
...
第14次 x为1
所以a+x累加总数
15*14+14*13+13*12...+2*1 + (14+13+12+...1)
计算 abs(b-y)
其中每个数合并的次数,从较大的数开始
15第1个参与运算15累加了14次
14第2个参与运算14累加了13次
...
2第14次参与运算2累加了1次
每1行合并时,y的值,并且y的值总小于b的值
每1行合并时,x的值
第1次 x为14
第2次 x为13
...
第14次 x为1
所以 abs(b-y)累加总数
15*14+14*13+13*12...+2*1 - (14+13+12+...1)
所以a+x+abs(b-y)总的累加数
15*14+14*13+13*12...+2*1 + (14+13+12+...1) + 15*14+14*13+13*12...+2*1 - (14+13+12+...1)
=(15*14+14*13+13*12...+2*1)*2
=(1*2 +2*3+3*4...12*13+13*14+14*15)*2
=((1^2 + 2^2 +3^2 +...12^2+13^2+14^2) + (1+2 +3 +...14))*2 --根据平方和公式 n(n+1)(2n+1)/6,等差数列求和 sn=(a1+an)∗n/2
=(14*(14+1)*(14*2+1)/6 + (1+14)*14/2)*2
=(1015 + 105)*2
=1120*2
=2240