CSP-J 初赛模拟卷(第 03 套)
入门级 C++ 语言试题
--- #### **一、单项选择题(共 15 题,每题 2 分,共计 30 分)** ( ) 1. 以下逻辑表达式的值恒为真的是( )。 A. `P ∨ (¬P ∧ Q) ∨ (¬P ∧ ¬Q)` B. `Q ∨ (¬P ∧ Q) ∨ (P ∧ ¬Q)` C. `P ∨ Q ∨ (P ∧ ¬Q) ∨ (¬P ∧ Q)` D. `P ∨ ¬Q ∨ (P ∧ ¬Q) ∨ (¬P ∧ ¬Q)` ( ) 2. 在 8 位二进制补码中,10101011 表示的数是十进制下的( )。 A. 43  B. -85  C. -43  D. -84 ( ) 3. 二进制数 11.01 在十进制下是( )。 A. 3.25  B. 4.125  C. 6.25  D. 11.125 ( ) 4. 把 64 位非零浮点数强制转换成32 位浮点数后,不可能( )。 A. 大于原数  B. 小于原数  C. 等于原数  D. 与原数符号相反 ( ) 5. 提出“存储程序”的计算机工作原理的是( )。 A. 克劳德·香农  B. 戈登·摩尔  C. 查尔斯·巴贝奇  D. 冯·诺依曼 ( ) 6. 如果开始时计算机处于小写输入状态,现在有一只小老鼠反复按照 CapsLock、 字母键 A、字母键 S 和字母键 D 的顺序循环按键,即 CapsLock、A、S、D、CapsLock、A、S、D……,屏幕上输出的第 81 个 字符是字母( )。 A. A  B. S  C. D  D. a ( ) 7. 原字符串中任意一段连续的字符所组成的新字符串称为子串。 则字符 “AAABBBCCC” 共有( )个不同的非空子串。 A. 3  B. 12  C. 36  D. 45 ( ) 8. 广度优先搜索时,需要用到的数据结构是( )。 A. 链表  B. 队列  C. 栈  D. 散列表 ( ) 9. 通常在搜索引擎中,对某个关键词加上双引号表示( )。 A. 排除关键词,不显示任何包含该关键词的结果 B. 将关键词分解,在搜索结果中必须包含其中的一部分 C. 精确搜索,只显示包含整个关键词的结果 D. 站内搜索,只显示关键词所指向网站的内容 ( ) 10. 将(2, 6, 10, 17)分别存储到某个地址区间为0~10 的哈希表中,如果哈希函数= ( ),将不会产生冲突,其中表示a除以b的余数。 A. $x$ mod 11  B. $x^{2}$ mod 11 C. $(2x)$ mod 11  D. $\lfloor sqrt(x)\rfloor$ mod 11,其中 $\lfloor sqrt(x)\rfloor$ 表示sqrt(x)下取整 ( ) 11. 考虑如下递归算法,则调用solve(7)得到的返回结果为( )。 ```cpp 1 solve(n) 2 if n<=1 return 1 3 else if n>=5 return n*solve(n-2) 4 else return n*solve(n-1) ``` A. 105  B. 840  C. 210  D. 420 ( ) 12. 给定一个含N个不相同数字的数组,在最坏情况下,找出其中最大或最小的数,至少需要 N-1 次比较操作。则最坏情况下,在该数组中同时找最大与 最小的数至少需要( )次比较操作。(⌈ ⌉表示向上取整,⌊ ⌋表示向下取整) A. $\lceil 3N/2 \rceil-2$  B. $\lfloor 3N/2 \rfloor-2$  C. $2N-2$  D. $2N-4$ ( ) 13. 一家四口人,至少两个人生日属于同一月份的概率是( )(假定每个人生日属于每个月份的概率相同且不同人之间相互独立)。 A. `1/12`  B. `1/144`  C. `41/96`  D. `3/4` ( ) 14. 一棵二叉树的前序遍历序列是ABCDEFG,后序遍历序列是CBFEGDA,则根结点的左子树的结点个数可能是( )。 A. 2  B. 3  C. 4  D. 5 ( ) 15. 2017 年 10 月 1 日是星期日,1999 年 10 月 1 日是( )。 A. 星期三  B. 星期日  C. 星期五  D. 星期二 --- #### **二、阅读程序(程序输入不超过数组或字符串定义的范围,判断题正确填 √,错误填 ×;共 18 小题,共计 38.5 分,各小题分值见题目)** **(1)** ```cpp 1 #include 2 #include 3 using namespace std; 4 5 char encoder[26] = {'C','S','P',0}; 6 char decoder[26]; 7 8 string st; 9 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 } ``` **判断题** ( ) 16. (1.5分) 输入的字符串应当只由大写字母组成,否则在访问数组时可能越界。( ) ( ) 17. (1.5分) 若输入的字符串不是空串,则输入的字符串与输出的字符串一定不一样。( ) ( ) 18. (1.5分) 将第 12 行的 `i < 26` 改为 `i < 16`,程序运行结果不会改变。( ) ( ) 19. (1.5分) 将第 26 行的 `i < 26` 改为 `i < 16`,程序运行结果不会改变。( ) **单选题** ( ) 20. (3分) 若输出的字符串为 `ABCABCABCA`,则下列说法正确的是( )。 A. 输入的字符串中既有 S 又有 P  B. 输入的字符串中既有 S 又有 B C. 输入的字符串中既有 A 又有 P  D. 输入的字符串中既有 A 又有 B ( ) 21. (3分) 若输出的字符串为 `CSPCSPCSPCSP`,则下列说法正确的是( )。 A. 输入的字符串中既有 P 又有 A  B. 输入的字符串中既有 S 又有 R C. 输入的字符串中既有 A 又有 S  D. 输入的字符串中既无 S 又无 A **(2)** ```cpp 1 #include 2 #include 3 using namespace std; 4 int n, m; 5 int f[101][101]; 6 int F[101][101]; 7 int main(){ 8 scanf("%d%d",&n,&m);//n的值在1到100之间 9 memset(f,-1,sizeof(f)); 10 for(int i = 1; i <= m; i++) { 11 int u,v,w;//w的值在0到10000之间 12 scanf("%d%d%d",&u,&v,&w); 13 f[u][v]=f[v][u]=w; 14 } 15 for(int k = 1; k <= n; k++) 16 for(int i=1;i <=n; i++) 17 for(int j=1;j<= n; j++) 18 if(f[i][k]!=-1&&f[k][j]!=-1) 19 if(f[i][j]==-1||f[i][j]>f[k][j]+f[i][k]) 20 f[i][j]=f[i][k]+f[k][j]; 21 int ans=2147483647; 22 for(int i=1;i<=n;i++) 23 for(int j=1;j<=n; j++){ 24 for(int x=1;x<=n; x++) 25 for(int y=1;y<=n; y++) 26 F[x][y]=f[x][y]; 27 F[i][j]=F[j][i]=0; 28 for(int x=1;x<= n; x++) 29 for(int y=1;y<=n; y++) 30 if(F[x][y]==-1||F[x][y]>F[x][i]+F[i][y]) 31 F[x][y]=F[x][i]+F[i][y]; 32 for(int x=1;x<=n; x++) 33 for(int y=1;y<=n; y++) 34 if(F[x][y]==-1||F[x][y]>F[x][j]+F[j][y]) 35 F[x][y]=F[x][j]+F[j][y]; 36 int res=0; 37 for(int x=1;x<=n; x++) 38 for(int y=1;y 2 using namespace std; 3 const int V = 101; 4 int n, m, ans, e[V][V]; 5 bool visited[V]; 6 void dfs(int x, int len) 7 { 8 int i; 9 visited[x] = true; 10 if (len > ans) ans = len; 11 for (i = 1; i <= n; i++) 12 if ((!visited[i]) && (e[x][i] != -1)) 13 dfs(i, len + e[x][i]); 14 visited[x] = false; 15 } 16 int main() 17 { 18 int i, j, a, b, c; 19 cin >> n >> m; 20 for (i = 1; i <= n; i++) 21 for (j = 1; j <= n; j++) 22 e[i][j] = -1; 23 for (i = 1; i <= m; i++) { 24 cin >> a >> b >> c; 25 e[a][b] = c; 26 e[b][a] = c; 27 } 28 for (i = 1; i <= n; i++) 29 visited[i] = false; 30 ans = 0; 31 for (i = 1; i <= n; i++) 32 dfs(i, 0); 33 cout << ans << endl; 34 return 0; 35 } ``` 输入表示一个没有重边、自环的无向图,顶点编号为 1 到 $n$,且 $1\le n\le100$、边权为正整数。 **判断题** ( ) 28. (1.5分) 第 19 行的输入中,如果满足 $m=n(n-1)/2$,则第 20~22 行的初始化可以省略。( ) ( ) 29. (1.5分) 将第 31 行改为 `for (i = n; i >= 1; i--)`,程序结果不受影响。( ) **单选题** ( ) 30. (1.5分) 若输入如下,则程序输出为( )。 ```text 4 2 1 2 1 3 4 1 ``` A. 8  B. 4  C. 2  D. 1 ( ) 31. (3分) 若输入如下,则程序输出为( )。 ```text 4 6 1 2 1 2 3 1 3 4 1 4 1 1 1 3 1 2 4 1 ``` A. 1  B. 3  C. 5  D. 7 ( ) 32. (3分) 若输入如下,则程序输出为( )。 ```text 4 3 1 2 10 2 3 20 3 1 30 ``` A. 30  B. 50  C. 90  D. 120 ( ) 33. (3分) 若输入如下,则程序输出为( )。 ```text 4 6 1 2 10 2 3 20 3 4 30 4 1 40 1 3 50 2 4 60 ``` A. 60  B. 100  C. 150  D. 200 --- #### **三、完善程序(程序输入不超过数组或字符串定义的范围;共 10 小题,共计 29 分,各小题分值见题目)** **(1)** (封禁xxs)现有n个xxs(编号为1到n),每个xxs都有一个关注者,第i个xxs的关注者是a_i。现在管理员要将其中的一些xxs的账号封禁,但需要注意的是如果封禁了第i个人,那么为了不打草惊蛇,就不能封禁他的关注者a_i。现在想知道最多可以封禁多少个xxs。 输入第一行是一个不超过300000的整数n,第二行是n个1到n的整数表示。 输出一行,一个整数表示答案。 ```cpp 1 #include 2 using namespace std; 3 #define MAXN 300005 4 int n, ans=0, a[MAXN], in[MAXN]={0}; 5 bool vis[MAXN]={0}; 6 void dfs(int cur, int w){ 7 if(vis[cur]) 8 return; 9 vis[cur]=true; 10 if(w==1) ans++; 11 __(1)__ 12 if(__(2)__) 13 dfs(a[cur], __(3)__); 14 } 15 int main(){ 16 scanf("%d",&n); 17 for(int i=1;i <=n; i++) { 18 scanf("%d", &a[i]); 19 in[a[i]]++; 20 } 21 for(int i=1;i <= n; i++) 22 if(!in[i]) __(4)__; 23 for(int i=1;i<=n; i++) 24 if(__(5)__) dfs(i,0); 25 printf("%d\n",ans); 26 return 0; 27 } ``` ( ) 34. (3分) (1)处应填 A. `a[cur]=cur;`  B. `in[a[cur]]=0;`  C. `in[a[cur]]--;`  D. `in[cur]--;` ( ) 35. (3分) (2)处应填 A. `in[a[cur]] != 0 || w == 1`  B. `in[a[cur]==0 | w==0` C. `in[a[cur]!=0 | w==0`  D. `in[a[cur]]==0 | w==1` ( ) 36. (3分) (3)处应填 A. 0  B. 1  C. w  D. 1-w ( ) 37. (3分) (4)处应填 A. `dfs(i,1)`  B. `dfs(i, 0)`  C. `dfs(a[i], 1)`  D. `dfs(a[i], 0)` ( ) 38. (3分) (5)处应填 A. `!in[i]`  B. `in[i]`  C. `!vis[i]`  D. `vis[l]` **(2)** 完善程序: (二叉查找树)二叉查找树具有如下性质:每个节点的值都大于其左子树上所有节点的值。小于其右子树上所有节点的值。试判断一棵树是否为二叉查找树。输入的第一行包含一个整数 $n$,表示这棵树有 $n$ 个顶点,编号分别为 $1,2,\dots ,n$,其中编号为1的为根结点。之后的第1行有三个数value, left_child, right_child,分别表示该节点关键字的值、左子节点的编号、右子节点的编号;如果不存在左子节点或右子节点,则用0代替。输出1表示这棵树是二叉查找树,输出0则表示不是。 ```cpp 1 #include 2 using namespace std; 3 const int SIZE = 100; 4 const int INFINITE = 1000000; 5 struct node 6 { 7 int left_child, right_child, value; 8 }; node a[SIZE]; 9 int is_bst( int root, int lower_bound, int upper_bound ) 10 { 11 int cur; 12 if ( root == 0 ) 13 return(1); 14 cur = a[root].value; 15 if ( (cur > lower_bound) && ( __(1)__ ) && (is_bst( a[root].left_child, lower_bound, cur ) == 1) && (is_bst( __(2)__, __(3)__, __(4)__ ) == 1) ) 16 return(1); 17 return(0); 18 } 19 int main() 20 { 21 int i, n; cin >> n; 22 for ( i = 1; i <= n; i++ ) 23 cin >> a[i].value >> a[i].left_child >> a[i].right_child; 24 cout << is_bst( __(5)__, -INFINITE, INFINITE ) << endl; 25 return(0); 26 } ``` | P/Q | Q为true | Q为false | | --- | --- | --- | | P为true | P=1&&Q=1 | P=1&&Q=0 | | P为false | P=0&&Q=1 | P=0&&Q=0 | ( ) 39. (3分) (1)处应填:________________ ( ) 40. (3分) (2)处应填:________________ ( ) 41. (3分) (3)处应填:________________ ( ) 42. (3分) (4)处应填:________________ ( ) 43. (2分) (5)处应填:________________