2020年CSP-J认证 CCF非专业级别软件能力认证第一轮真题--阅读程序题

2020 CCF认证第一轮(CSP-J)真题

二、阅读程序题

(程序输入不超过数组或字符串定义的范围,判断题正确填√错误填X;除特殊说明外,判断题 1.5分,选择题3分,共计4 分)

第一题

01 #include <cstdlib>
02 #include <iostream>
03 using namespace std;
04
05 char encoder[26]= {'C','S','P',0};
06 char decoder[26];
07
08 string st;
09
10 int main(){
11    int k=0;
12    for (int i=0;i<26;++i)
13        if (encoder[i] != 0) ++k;
14    for (char x='A';x<='Z;++x){
15        bool flag = true;
16        for (int i=0;i<26; ++i)
17            if (encoder[i] == x){
18                flag = false;
19                break;
20            }
21        if (flag){
22            encoder[k] = x;
23            ++k;
24        }
25    }
26    for (int i=0;i<26;++i)
27        decoder[encoder[i]-'A']=i+'A';
28    cin >> st;
29    for (int i=0;i<st.length();++i)
30        st[i] = decoder[st[i] -'A'];
31    cout << st;
32    return 0;
33}

程序分析

主要考查小朋友们读写程序能力和逻辑思维能力,此程序实现的一个加密解密的功能;它使用一个26个元素的数组 encoder 和一个26个元素的数组 decoder,分别用于加密和解密。

程序首先初始化 encoder 数组为 {'C','S','P',0},然后通过遍历数组找到不为零的元素个数,并输出这些元素。接着,程序遍历从 A 到 Z 的所有字母,检查它们是否已经在 encoder 数组中出现过。如果未出现过,则将该字母添加到 encoder 数组中。程序也会相应地更新 decoder 数组,以便进行解密。

然后,程序从用户获取一个字符串,并将该字符串中的每个字符用相应的解码方式进行解密。最后,程序输出解密后的字符串。

总之,这段程序实现了一个简单的加密和解密功能,其中加密方式是将大写的C、S、P三个字母替换为 大写的A、B、C三个字母,具体加密前字母和加密后字母如下:

加密前:ABCDEFGHIJKLMNOPQRSTUVWXYZ

加密后:DEAFGHIJKLMNOPQCRSBTUVWXYZ

判断题

1)、输入的字符串应当只由大写字母组成,否则在访问数组时可能越界

2)、若输入的字符串不是空串,则输入的字符串与输出的字符串一定不一样

3)、将第 12行的“i<26”改为“i<16”,程序运行结果不会改变

4)、将第 26行的"i<26”改为“i<16”,程序运行结果不会改变

答案:1√ 2 × 3 √ 4 ×

答案分析:

1、从程序分析可以得出输入的只能是26个大写字母

2、输入的是S后面的字母输出的就是一样的

3、第12行的作用是读取encoder数组里面的个数,程序中只给出CSP三个,所以改成16不影响,改成6都可以,只要超过encoder数组的个数就行

4、第26是对26个字母进行解码,如果改成16了,会发现后面的一部分就会出错

单选题

5)、出的字符串为“ABCABCABCA”,则下列说法正确的是

A、输入的字符串中既有 S 又有 P

B、输入的字符串中既有 S 又有 B

C、输入的字符串中既有 A 又有 P

D、输入的字符串中既有 A 又有 B

答案:A

答案分析:因为输出的结果中有B和C,所以输入的字符串就是S和P,所以答案A

6)、若输出的字符串为“CSPCSPCSPCSP”,则下列说法正确的是

A、输入的字符串中既有 P 又有 K

B、输入的字符串中既有 J 又有 R

C、输入的字符中中既有 J 又有 K

D、输入的字符串中既有 P又有 R

答案:D

答案分析:因为输出的结果中有C和S,所以输入的字符串就是P和R,所以答案D

第二题

1 #include<iostream>
2 using namespace std;
3
4 long long n, ans;
5 int k, len;
6 long long d[1000000];
7
8 int main(){
9 	cin >> n >> k;
10	d[0] = 0;
11 	len= 1;
12	ans = 0;
13	for (long long i = 0; i<n; ++i) {
14		++d[0];
15		for (int j = 0;j + 1<len; ++j){
16			if (d[j] == k){
17				d[j] = 0;
18				d[j + 1] += 1;
19				++ans;
20			}
21		}
22		if (d[len- 1] == k){
23			d[len - 1] = 0;
24			d[len] =1;
25			++len;
26			++ans;
27		}
28	}
29	cout << ans << endl;
30	return 0;
31 }

程序分析

主要考查小朋友们读写程序能力和逻辑思维能力,此程序小朋友们不认真理解还是比较容易出错的,甚至有可能看不懂题目;此程序其实要实现的功能是将十进制数n,转换成对应的k进制数,输出的结果是在转换的过程中总的进位的次数,也就是ans;其中的len表示的是长度;当k为1时,n为1,1进制的1,len 为2,所以错误;输入n为1且 k > 1 时,ans == n;n转化为 len 位的 k 进制数字值 最大值为 k^len - 1 ,因此k^len>n。

判断题

1)、若k=1,则输出ans 时,len=n。

2)、若 k>1,则输出ans 时,len 一定小于n。 

3)、若 k>1,则输出ans 时,k^{len}一定大于n。 

答案:1× 2 ×3 √ 

单选题

4)、 若输入的n等于10^{15},输入的k 为1,则输出等于

A、1

B、\left ( 10^{30}-10^{15} \right )/2

C、\left ( 10^{30}+10^{15} \right )/2

D、10^{15}

答案:D

5)、若输入的n等于205,891,132,094,649(即3^{30}),输入的k为3,则输出等于

A、3^{30}

B、\left ( 3^{30}-1 \right )/2

C、3^{30}-1

D、\left ( 3^{30}+1 \right )/2

答案:B

6)、若输入的n 等于 180,01,02,000,098,输入的k为10,则输出等于

A、11,112,222,444,543

B、11,122,222,444,453

C、11,122,222,444,543

D、11,112,222,444,453

答案:B

考点分析:4、当输入的 k 为 1 时,表示的是1进制,所以每一次都会进,len为2,但是后面触发不了len++的条件,结果就是,len一直是2,每次 d[0]++ 都会进位,输出 ans == n。

5、第1位,每k次运算进位1次;
第2位,每k^{2}次运算进位1次;
……
因此第1位,会产生330/3次进位,第2位会产生330/3^{2}次进位……最后一位,会产生1次进位。
因此答案 = 3^{30} / 3 + 3^{30}/3^{2} + … + 1
根据等比数列求和公式Sn = (3^{30}– 1) / (3 - 1)

6、根据上面的分析,可以得到答案为B

第三题

#include <algorithm>
#include <iostream>
using namespace std;

int n;
int d[50][2];
int ans;

void dfs(int n,int sum) {
	if (n == 1) {
		ans = max(sum, ans);
		return;
	}		
	for (int i=1;i<n;++i){
		int a= d[i -1][0],b = d[i - 1][1];
		int x=d[i][0],y = d[i][1];
		d[i-1][0]=a+x;
		d[i- 1][1]=b+y;
		for (int j=i;j<n-1;++j)
			d[j][0] = d[j + 1][0],d[j][1] = d[j + 1][1];
		int s=a+x+abs(b- y);
		dfs(n-1,sum +s);
		for (int j=n-1;j>i;--j)
			d[j][0] = d[j - 1][0],d[j][1]= d[j-1][1];
		d[i- 1][0]=a,d[i- 1][1]=b;
		d[i][0] =x,d[i][1] = y;
	}
}

int main() {
	cin >>n;
	for (int i=0;i<n;++i)
		cin >>d[i][0];
	for (int i=0;i<n;++i)
		cin >> d[i][1];
	ans = 0;
	dfs(n,0);
	cout << ans << endl;
	return 0;
}

程序分析

主要考查小朋友们读写程序能力和逻辑思维能力,程序通过递归实现深度优先搜索(DFS)来寻找满足条件的子数组。在递归过程中,维护一个当前已选取的元素的和sum,每次扩展当前子数组时,将当前位置的元素加到前面已经选取的元素的和上,然后将这个和加上当前位置与下一个位置的差的绝对值,作为新的sum值。递归完成后,更新答案ans为当前和sum与ans的最大值。

假设输入的 n 是不超过 5 的正整数,d[i][0]d[i][1]都是不超过10000的正整数,完成下面的判断题和单选题:

判斯题

1) 输入 n 为0,此程序可能会死循环或发生运行错误

2) 若输入n为20,接下来的输入全为0,则输出为 0

3) 输出的数一定不小于输入的 d[i][0]和 d[i][1]的任意一个

答案:1× 2√ 3  ×

答案分析:输入0,啥也不做,直接输出0;输入20个0,求和依然是0,ans也是0;输入的值也有可能小于输入的值,比如输入n=2,0 0 和 3 3,这时输出的是0

单选题

4) 若输入的n为20,接下来的输入是 20个9和20个0,则输出为

A.1890        B.1881        C.1908        D.1917

答案:B

5) 若输入的n为3,接下来的输入是 3 个0和3 个5,则输出为

A.2000        B. 2010        C.2030        D.2020

答案:C

6) 若输入的n 为 15,接下来的输入是15到1,以及15 到1,则输出为

A. 2440        B. 2220        C.2240        D. 2420

答案:C

考点分析:

4、第二列为0,加0等于没加不用管,可以忽略
第1次合并:9+9=9*2
第2次合并:18+9=9*
3
第3次合并:27+9=9*4

第19次得到:9*20
因此和 = 9*2 + 9*3 + … + 9 * 20 = 1881

5、第1次合并:5-5=0
第2次合并:5+5-5=5=5*1
第3次合并:10+5-5=10=5*
2

第29次合并:5*30-5=5*28
求和 = 5 * (1 + 2 + … + 28) = 2030

6、对于第1列:
第1次合并 = 15+14
第2次合并 = 15+14+13

第14次合并 = 15+14+13+12+…+1

15*14+14*14+13*13+…+1*1 = 1225

对于第2列:
第1次合并 = 15-14
第2次合并 = 15+14-13
第3次合并 = 15+14+13-12
……
第14次合并 = 15+14+13+12+…+2-1
15*13+14*12+…+3*1=1001,最后加上14个1:1015
最终答案是:2240

猜你喜欢

转载自blog.csdn.net/frank2102/article/details/131173715