2020 年 12 月青少年软编等考 C 语言二级真题解析

2020 年 12 月青少年软编等考 C 语言二级真题解析

码农世界 2024-05-23 前端 75 次浏览 0个评论

目录

  • T1. 数组指定部分逆序重放
    • 思路分析
    • T2. 简单密码
      • 思路分析
      • T3. 错误探测
        • 思路分析
        • T4. 奇数单增序列
          • 思路分析
          • T5. 话题焦点人物
            • 思路分析

              T1. 数组指定部分逆序重放

              将一个数组中的前 k k k 项按逆序重新存放。例如,将数组 8 , 6 , 5 , 4 , 1 8,6,5,4,1 8,6,5,4,1 前 3 3 3 项逆序重放得到 5 , 6 , 8 , 4 , 1 5,6,8,4,1 5,6,8,4,1。

              时间限制:1 s

              内存限制:64 MB

              • 输入

                输入为两行:

                第一行两个整数,以空格分隔,分别为数组元素的个数 n n n, 1 < n < 100 1 < n < 100 1

                第二行是 n n n 个整数,每两个整数之间用空格分隔。

              • 输出

                输出为一行:输出按题目要求逆序后数组的整数,每两个整数之间用空格分隔。

              • 样例输入
                5 3
                8 6 5 4 1
                
              • 样例输出
                5 6 8 4 1
                

                思路分析

                此题考查一维数组的基本应用,属于入门题。

                可以使用循环遍历数组下标 1 ∼ k / 2 1\sim k/2 1∼k/2 的范围,在循环体内执行 swap(a[i], a[k+1-i]); 即可实现前 k k k 项逆序重放。也可以使用 reverse 函数,更加方便简单。

                /*
                 * Name: T1.cpp
                 * Problem: 数组指定部分逆序重放
                 * Author: Teacher Gao.
                 * Date&Time: 2024/05/23 19:24
                 */
                #include 
                #include 
                using namespace std;
                int main()
                {
                    int n, k;
                    int a[105];
                    
                    cin >> n >> k;
                    for (int i = 1; i <= n; i++) {
                        cin >> a[i];
                    }
                    reverse(a + 1, a + k + 1);
                    for (int i = 1; i <= n; i++) {
                        cout << a[i] << " ";
                    }
                    return 0;
                }
                

                T2. 简单密码

                Julius Caesar \text{Julius Caesar} Julius Caesar 曾经使用过一种很简单的密码。对于明文中的每个字符,将它用它字母表中后 5 5 5 位对应的字符来代替,这样就得到了密文。比如字符 A A A 用 F F F 来代替。如下是密文和明文中字符的对应关系。

                密文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

                明文:V W X Y Z A B C D E F G H I J K L M N O P Q R S T U

                你的任务是对给定的密文进行解密得到明文。你需要注意的是,密文中出现的字母都是大写字母。密文中也包括非字母的字符,对这些字符不用进行解码。

                时间限制:1 s

                内存限制:64 MB

                • 输入

                  一行,给出密文,密文不为空,而且其中的字符数不超过 200 200 200。

                • 输出

                  输出一行,即密文对应的明文。

                • 样例输入
                  NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
                  
                • 样例输出
                  IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES
                  

                  思路分析

                  此题考查字符串的基本操作,属于入门题。

                  可以建立两个数组 a 和 b,用于构建密文和明文之间的对应关系。然后遍历密文字符串 str,对于每一个 str[i],在密文数组 a 中进行检测。若匹配成功,则将 str[i] 修改为对应的明文。最后输出 str 即可。此为循环嵌套的写法,容易想得到,但是代码长。

                  仔细观察密文和明文的对应关系不难发现,这个对应关系是一个循环移位的操作, F ∼ Z F \sim Z F∼Z 分别减去 5 5 5 即可得到对应明文,至于 A ∼ E A \sim E A∼E,可以减去 5 5 5 之后再加上 26 26 26 得到对应明文。此为单层循环的写法,程序效率得到了很大的提升。

                  /*
                   * Name: T2.cpp
                   * Problem: 简单密码
                   * Author: Teacher Gao.
                   * Date&Time: 2024/05/23 19:37
                   */
                  #include 
                  #include 
                  using namespace std;
                  int main()
                  {
                  	string str;
                  	getline(cin, str);
                  	int len = str.size();
                  	for (int i = 0; i < len; i++) {
                  		if ('A' <= str[i] && str[i] <= 'Z') {
                  			str[i] = str[i] - 5;
                  			if (str[i] < 'A') {
                  				str[i] = str[i] + 26;
                  			}
                  		}
                  	}
                  	cout << str << endl;
                  	return 0;
                  }
                  

                  T3. 错误探测

                  给定 n × n n \times n n×n 由 0 0 0 和 1 1 1 组成的矩阵,如果矩阵的每一行和每一列的 1 1 1 的数量都是偶数,则认为符合条件。

                  你的任务就是检测矩阵是否符合条件,或者在仅改变一个矩阵元素的情况下能否符合条件。“改变矩阵元素” 的操作定义为 0 0 0 变成 1 1 1 或者 1 1 1 变成 0 0 0。

                  时间限制:1 s

                  内存限制:64 MB

                  • 输入

                    输入 n + 1 n + 1 n+1 行:

                    第 1 1 1 行为矩阵的大小 n n n, 0 < n < 100 0 < n < 100 0

                    以下 n n n 行为矩阵的每一行的元素,元素之间以一个空格分开。

                  • 输出

                    如果矩阵符合条件,则输出 OK;如果矩阵仅改变一个矩阵元素就能符合条件,则输出需要改变的元素所在的行号和列号,以一个空格分开。如果不符合以上两条,输出 Corrupt。

                  • 样例输入 1
                    4
                    1 0 1 0
                    0 0 0 0
                    1 1 1 1
                    0 1 0 1
                    
                  • 样例输出 1
                    OK
                    
                  • 样例输入 2
                    4
                    1 0 1 0
                    0 0 1 0
                    1 1 1 1
                    0 1 0 1
                    
                  • 样例输出 2
                    2 3
                    
                  • 样例输入 3
                    4
                    1 0 1 0
                    0 1 1 0
                    1 1 1 1
                    0 1 0 1
                    
                  • 样例输出 3
                    Corrupt
                    

                    思路分析

                    此题考察二维数组的用法,属于入门题。

                    对输入数据分别按行和列统计 1 1 1 的个数,并分别记录下 1 1 1 的个数为奇数个的行数 totr 和行号 row、列数 totc 和列号 col。若行数 totr 或列数 totc 大于 1 1 1,则不可行;若行数 totr 和列数 totc 均等于 1 1 1,则修改行号 row 和列号 col 的交叉位置即可;若行数 totr 和列数 totc 均等于 0 0 0,则符合条件。

                    事实上我们可以使用两个一维数组来替代二维数组,换言之,只需统计,无需存储。甚至更进一步,可以只用一个一维数组来统计每列 1 1 1 的个数。因为程序是按行进行输入的,每行的情况可以在输入的过程中就进行统计求解。

                    /*
                     * Name: T3.cpp
                     * Problem: 错误探测
                     * Author: Teacher Gao.
                     * Date&Time: 2024/05/23 19:54
                     */
                    #include 
                    using namespace std;
                    int main()
                    {
                    	int n, x;
                    	int row[105] = {0}, col[105] = {0};
                    	cin >> n;
                    	for (int i = 1; i <= n; i++) {
                    		for (int j = 1; j <= n; j++) {
                    			cin >> x;
                    			row[i] = row[i] + x;	// 按行统计
                    			col[j] = col[j] + x;	// 按列统计
                    		}
                    	}
                    	
                    	// 按行查找
                    	int totr = 0, rowi;
                    	for (int i = 1; i <= n; i++) {
                    		if (row[i] % 2) {
                    			totr++;
                    			rowi = i;
                    		}
                    	}
                    	
                    	// 按列查找
                    	int totc = 0, coli;
                    	for (int i = 1; i <= n; i++) {
                    		if (col[i] % 2) {
                    			totc++;
                    			coli = i;
                    		}
                    	}
                    	
                    	// 检测结果
                    	if (totr > 1 || totc > 1) {
                    		cout << "Corrupt" << endl;
                    	}
                    	else if (totr == 1 && totc == 1) {
                    		cout << rowi << " " << coli << endl;
                    	}
                    	else {
                    		cout << "OK" << endl;
                    	}
                    	return 0;
                    }
                    

                    T4. 奇数单增序列

                    给定一个长度为 n ( ≤ 500 ) n(\le 500) n(≤500) 的正整数序列,请将其中的所有奇数取出,并按升序输出。

                    时间限制:1 s

                    内存限制:64 MB

                    • 输入

                      共 2 2 2 行:

                      第 1 1 1 行为 n n n;

                      第 2 2 2 行为 n n n 个正整数,其间用空格间隔。

                    • 输出

                      增序输出的奇数序列,数据之间以逗号间隔。数据保证至少有一个奇数。

                    • 样例输入
                      10
                      1 3 2 6 5 4 9 8 7 10
                      
                    • 样例输出
                      1,3,5,7,9
                      

                      思路分析

                      此题考察排序算法,属于入门算法题。

                      由于数据量较小, O ( n 2 ) O(n^2) O(n2) 的排序算法(冒泡、选择、插入)均可以解决此题。当然了,更简单的方法是用 sort 函数。排完序之后将奇数进行输出即可。至于输出格式中的逗号,可以参考 2022 年 6 月青少年软编等考 C 语言一级真题解析的 T5。

                      /*
                       * Name: T4.cpp
                       * Problem: 奇数单增序列
                       * Author: Teacher Gao.
                       * Date&Time: 2024/05/23 20:10
                       */
                      #include 
                      #include 
                      using namespace std;
                      int main()
                      {
                      	int n, a[505];
                      	cin >> n;
                      	for (int i = 1; i <= n; i++) {
                      		cin >> a[i];
                      	}
                      	sort(a + 1, a + n + 1);
                      	bool flag = 1;
                          for (int i = 1; i <= n; i++) {
                              if (a[i] % 2) {
                      			if (flag) {
                      				flag = 0;
                      			}
                      			else {
                      				cout << ",";
                      			}
                                  cout << i;
                              }
                          }
                      	return 0;
                      }
                      

                      T5. 话题焦点人物

                      微博提供了一种便捷的交流平台。一条微博中,可以提及其它用户。例如 Lee \text{Lee} Lee 发出一条微博为:“期末考试顺利 @ Kim \text{Kim} Kim @ Neo \text{Neo} Neo”,则 Lee \text{Lee} Lee 提及了 Kim \text{Kim} Kim 和 Neo \text{Neo} Neo 两位用户。

                      我们收集了 n ( 1 < n < 10000 ) n(1 < n < 10000) n(1

                      通过分析这些数据,我们希望发现大家的话题焦点人物,即被提及最多的人(题目保证这样的人有且只有一个),并找出那些提及它的人。

                      时间限制:1 s

                      内存限制:64 MB

                      • 输入

                        输入共两部分:

                        第一部分是微博数量 n n n, 1 < n < 10000 1 < n < 10000 1

                        第二部分是 n n n 条微博,每条微博占一行,表示为:发送者序号 a a a,提及人数 k k k, 0 ≤ k ≤ 20 0 \le k \le 20 0≤k≤20,然后是 k k k 个被提及者序号 b 1 , b 2 . . . b k b_1,b_2...b_k b1​,b2​...bk​;其中 a a a 和 b 1 , b 2 . . . b k b_1,b_2...b_k b1​,b2​...bk​ 均为大于 0 0 0 小于等于 100 100 100 的整数。相邻两个整数之间用单个空格分隔。

                      • 输出

                        输出分两行:

                        第一行是被提及最多的人的序号;

                        第二行是提及它的人的序号,从小到大输出,相邻两个数之间用单个空格分隔。同一个序号只输出一次。

                      • 样例输入
                        5
                        1 2 3 4
                        1 0
                        90 3 1 2 4
                        4 2 3 2
                        2 1 3
                        
                      • 样例输出
                        3
                        1 2 4
                        

                        思路分析

                        此题考察二维数组的应用,有一定难度,找对方法之后则可以轻松拿下。

                        乍一看,此题考查的是数组的查找与统计,但是看到第二问就比较麻烦了,多数同学会选择采用循环嵌套的方式进行查找,不仅代码复杂,而且效率不高。结合一下,我们可以用 vector 解决这个麻烦的问题,将提到 i i i 号用户的用户,存储到一个 vector 中。之后对多个 vector 的 size 求出最大值,则最大值对应的那个 vector 的下标就是话题焦点人物。再将这个 vector 进行排序输出即可。

                        /*
                         * Name: T5.cpp
                         * Problem: 话题焦点人物
                         * Author: Teacher Gao.
                         * Date&Time: 2024/05/23 20:18
                         */
                        #include 
                        #include 
                        #include 
                        using namespace std;
                        int main()
                        {
                        	int n, a, k, x;
                        	vector L[105];
                        	cin >> n;
                        	for (int i = 1; i <= n; i++) {
                        		cin >> a >> k;
                        		for (int j = 1; j <= k; j++) {
                        			cin >> x;
                        			L[x].push_back(a);		// a 提到了 x,因此将 a 存入 x 对应的 vector
                        		}
                        	}
                        	int ans = 0;
                        	for (int i = 1; i <= 100; i++) {
                        		if (L[i].size() > ans) {
                        			ans = L[i].size();
                        		}
                        	}
                        	sort(L[ans].begin(), L[ans].end());
                        	cout << ans << endl;
                        	for (auto i : L[ans]) {
                        		cout << i << " ";
                        	}
                        	return 0;
                        }
                        

转载请注明来自码农世界,本文标题:《2020 年 12 月青少年软编等考 C 语言二级真题解析》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,75人围观)参与讨论

还没有评论,来说两句吧...

Top