信息学奥赛初赛天天练-49-CSP-J2020阅读程序3-连续自然数平方和、等差数列求和、深度优先搜索、回溯、贪心算法

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

posted @ 2024-07-29 16:31  new-code  阅读(0)  评论(0编辑  收藏  举报