#CSPJMOCK11. CSP-J 初赛模拟题 11
CSP-J 初赛模拟题 11
一、单项选择(满分 30 分,每题 2 分)
- 关于 ASCII,下面哪个说法是正确的?
{{ select(1) }}
- ASCII 码就是键盘上所有键的唯一编码。
- 一个 ASCII 码使用一个字节的内存空间就能够存放。
- 最新扩展的 ASCII 编码方案包含了汉字和其他欧洲语言的编码。
- ASCII 码是英国人主持制定并推广使用的。
- 分辨率为 、16 位色的位图,存储图像信息所需的空间为( )。
{{ select(2) }}
- 2812.5 KB
- 4218.75 KB
- 4320 KB
- 2880 KB
- 若某算法的计算时间表示为递推关系式:
则该算法的时间复杂度为( )。
{{ select(3) }}
- 有向图中每个顶点的度等于该顶点的( )。
{{ select(4) }}
- 入度
- 出度
- 入度和出度之和
- 入度和出度之差
- 在 C++ 语言中,表达式
23|2^5的值是( )。
{{ select(5) }}
- 18
- 1
- 23
- 32
- 的结果不是( )。
{{ select(6) }}
- 已知 7 个结点的二叉树的先根遍历是
1 2 4 5 6 3 7(数字为结点的编号,以下同),后根遍历是4 6 5 2 7 3 1,则该二叉树的不可能的中根遍历是( )。
{{ select(7) }}
4 2 6 5 1 7 34 2 5 6 1 3 74 2 3 1 5 6 74 2 5 6 1 7 3
- 一个圆上有 6 个顶点
ABCDEF,以其中三点为顶点,可以连出多少个三角形?
{{ select(8) }}
- 18
- 6
- 120
- 20
- 从 A 点只能向上或者向右走,沿方格线到达 B 点,共有多少种走法?

{{ select(9) }}
- 7
- 35
- 15
- 20
- 自然数中 0~9 任意选四个不同的数,组成一个四位数,共可以组成多少个这样的四位数?
{{ select(10) }}
- 5040
- 4536
- 3024
- 210
- 一个数列,其中任意五个相邻项之和为 2010。已知第一个数是 1,第 9 个数是 9,第 17 个数是 9,第 2008 个数是 3,求第 2010 个数是多少?
{{ select(11) }}
- 1988
- 1998
- 2022
- 2032
- 在两条直线上,分别有五个点和四个点,从中任选三个点组成三角形,有( )种情况。

{{ select(12) }}
- 84
- 70
- 72
- 96
- 完全二叉树共有 个结点,则它的叶节点数是( )。
{{ select(13) }}
- 在含有 个元素的双向链表中查询是否存在关键字为 的元素,最快情况下运行的时间复杂度是( )。
{{ select(14) }}
- 有以下结构体说明和变量定义,如图所示,指针
p,q,r分别指向一个链表中的三个续结点。
struct node {
int data;
struct node *next;
} *p, *q, *r;

现要将 q 和 r 所指结点的先后位置交换,同时要保持链表的连续,以下程序段中错误的是( )。
{{ select(15) }}
q->next = r->next; p->next = r; r->next = q;p->next = r; q->next = r->next; r->next = q;q->next = r->next; r->next = q; p->next = r;r->next = q; q->next = r->next; p->next = r;
二、阅读程序(满分 40 分,判断题 1.5 分,选择题除特殊说明外 3 分)
判断题请选择“正确”或“错误”。
阅读 1
01 #include <bits/stdc++.h>
02 long long n, m, t, a[1000005];
03 int main() {
04 scanf("%lld%lld", &n, &m);
05 while (m > 0) {
06 t++;
07 m--;
08 if (m <= 0)
09 break;
10 a[t] = a[t - 1] + 1;
11 while (m > (1 << n - a[t]) && a[t] <= n) {
12 m -= 1 << n - a[t];
13 a[t]++;
14 }
15 }
16 if (t != 1)
17 for (int i = 1; i < t; i++)
18 printf("%lld ", a[i]);
19 else
20 puts("0");
21 return 0;
原卷程序截图到第 21 行为止,未显示
main函数最后的右花括号。
- 第 20 行的
"0"改成'0',程序运行会报错。( )
{{ select(16) }}
- 正确
- 错误
- 输入的
n如果是负整数,程序运行不会报错。( )
{{ select(17) }}
- 正确
- 错误
- 第 10 行的功能是对
a数组求前缀和。( )
{{ select(18) }}
- 正确
- 错误
- 输入的
n最大可以到 1000000。( )
{{ select(19) }}
- 正确
- 错误
- 输入
4 12,输出( )。
{{ select(20) }}
02 32 3 41 2 3
- 当输入
n为 3,m为 1~8 之间的整数时,平均输出整数的个数(保留一位小数)是( )。
{{ select(21) }}
- 1.0
- 1.6
- 1.8
- 2.0
阅读 2
01 #include<iostream>
02 #include<cstring>
03 using namespace std;
04 string A,B;
05 char s1[2005],s2[2005];
06 int edit[2005][2005];
07 int dfs(int i,int j){
08 if(edit[i][j]!=-1)
09 return edit[i][j];
10 if(i==0)
11 return edit[i][j]=j;
12 if(j==0)
13 return edit[i][j]=i;
14 int bonus=1;
15 if(s1[i]==s2[j])
16 bonus=0;
17 return edit[i][j]=min(min(dfs(i-1,j)+1,dfs(i,j-1)+1),dfs(i-1,j-1)+bonus);
18 }
19 int main(){
20 cin>>A>>B;
21 memset(edit,-1,sizeof(edit));
22 int len1=A.length(),len2=B.length();
23 for(int i=1;i<=len1;i++)
24 s1[i]=A[i-1];
25 for(int i=1;i<=len2;i++)
26 s2[i]=B[i-1];
27 dfs(len1,len2);
28 cout<<edit[len1][len2];
29 return 0;
30 }
输入的字符串只包含小写字母 a~z。
- 第 8 行和第 21 行的
-1如果改成-2,程序运行结果可能不一样。( )
{{ select(22) }}
- 正确
- 错误
- 是输入的两个字符串长度的最大值,程序的时间复杂度为 。( )
{{ select(23) }}
- 正确
- 错误
- 输出的最小值为
-1。( )
{{ select(24) }}
- 正确
- 错误
len1和len2为执行完第 22 行后的值,输出的最大值为len1+len2。( )
{{ select(25) }}
- 正确
- 错误
- 输入为
sfdqxbw gfdgw,输出( )。
{{ select(26) }}
- 2
- 3
- 4
- 5
- **(4 分)**保证输入的两个字符串长度均为 100,且只包含小写字母
a~z。第一个字符串为"acegikmoqsuwyace...uwy...ace...moq",第二个字符串为"abcdefghijklmnopqrstuvwxy...abc...wxyabcd"(“...”表示省略了中间的字符),输出为( )。
{{ select(27) }}
- 4
- 13
- 50
- 96
阅读 3
01 #include<iostream>
02 #include<cstdio>
03 #define mod 9901
04 using namespace std;
05 int a,b,sa,n[10010][2],cot=0,ans=1;
06 int q(int ml,int nl){
07 int s=1;
08 while(nl>0){
09 if(nl%2==1){
10 s=(s%mod)*(ml%mod)%mod;
11 }
12 ml=ml*ml%mod;
13 nl=nl>>1;
14 }
15 return s%mod;
16 }
17 int sum(int x,int y){
18 int k=0;
19 y=y*b;
20 if(x%mod==1){
21 k=(y+1)%mod;
22 }
23 else{
24 k=(q(x%mod,y+1)-1)%mod*q((x-1)%mod,mod-2)%mod;
25 }
26
27 return k%mod;
28 }
29 int main(){
30 scanf("%d%d",&a,&b);
31 if(a==0){
32 printf("0\n");
33 return 0;
34 }
35 for(int i=2;i*i<=a;i++){
36 if(a%i==0){
37 cot++;
38 n[cot][0]=i;
39 n[cot][1]=1;
40 a=a/i;
41 while(a%i==0){
42 n[cot][1]++;
43 a=a/i;
44 }
45 }
46 }
47 if(a!=1){
48 cot++;
49 n[cot][0]=a;
50 n[cot][1]=1;
51 }
52 for(int i=1;i<=cot;i++){
53 ans=ans*sum(n[i][0],n[i][1])%mod;
54 }
55 printf("%d\n",(ans%mod+mod)%mod);
56 return 0;
57 }
- 第 35 行的
i*i改成i,运行结果不变。( )
{{ select(28) }}
- 正确
- 错误
- 第 3 行
9901换成1e9+7,运行结果不变。( )
{{ select(29) }}
- 正确
- 错误
n[cot][0]随着cot的增大而增大。( )
{{ select(30) }}
- 正确
- 错误
- 第 27 行删除
%mod,结果不变。( )
{{ select(31) }}
- 正确
- 错误
- 输入为
2 3,输出( )。
{{ select(32) }}
- 4
- 8
- 9
- 15
- 输出为 542,输入可能是以下哪组数据?( )
{{ select(33) }}
210 5210 6330 5330 6
- 输入为
217823 1,输出为( )。
{{ select(34) }}
- 1
- 2
- 9901
- 22
三、完善程序(满分 30 分,单选,每题 3 分)
完善 1
众所周知,2 的正整数次幂最后一位数总是不断的在重复 2,4,8,6,2,4,8,6…。我们说 2 的正整数次幂最后一位的循环长度是 4(实际上 4 的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象:
| 数字 | 循环 | 循环长度 |
|---|---|---|
| 2 | 2,4,8,6 | 4 |
| 3 | 3,9,7,1 | |
| 4 | 4,6 | 2 |
| 5 | 1 | |
| 6 | ||
| 7 | 7,9,3,1 | 4 |
| 8 | 8,4,2,6 | |
| 9 | 9,1 | 2 |
这时问题就出来了:是不是只有最后一位才有这样的循环呢?对于一个整数 的正整数次幂来说,它的后 位是否会发生循环?如果循环的话,循环长度是多少呢?
注意:
- 如果 的某个正整数次幂的位数不足 ,那么不足的高位看做是 0。
- 如果循环长度是 ,那么说明对于任意的正整数 , 的 次幂和 次幂的最后 位都相同。
- ,。
输入共一行,包含 2 个整数 和 。 和 之间用一个空格隔开,表示要求 的正整数次幂的最后 位的循环长度。
输出一个整数,表示循环长度。如果循环不存在,输出 -1。
试补全程序:
#include<bits/stdc++.h>
using namespace std;
int k;
struct BNR{
int a[105];
int len;
BNR(){
memset(a,0,sizeof(a));
len=0;
}
};
typedef BNR bign;
void cpy(①,bign y){
x.len=y.len;
for(int i=1;i<=x.len;i++)
x.a[i]=y.a[i];
}
void in(①){
char ch=getchar();x.len=0;
while(ch<'0'||ch>'9')ch=getchar();
while(ch<='9'&&ch>='0')
x.len++,x.a[x.len]=(int)ch-'0',ch=getchar();
for(int i=1;i<=x.len/2;i++)
swap(x.a[i],②);
}
void out(①){
for(int i=x.len;i>=1;i--)
cout<<x.a[i];
cout<<endl;
}
void AAA(①,bign y){
for(int i=1;i<=min(y.len,k);i++)
x.a[i]+=y.a[i];
x.len=0;
for(int i=1;i<=k;i++){
if(x.a[i])x.len=max(x.len,i);
x.a[i+1]+=x.a[i]/10,x.a[i]%=10;
}
}
bign z;
void BBB(①,bign y){
z.len=0;
memset(z.a,0,sizeof(z.a));
for(int i=1;i<=min(x.len,k);i++)
for(int j=1;③<=k;j++)
z.a[③] += x.a[i]*y.a[j];
for(int i=1;i<=k;i++)
{
if(z.a[i])z.len=max(z.len,i);
z.a[i+1]+=z.a[i]/10,z.a[i]%=10;
}
cpy(x,z);
}
int main()
{
bign n;
in(n);
cin>>k;
bign p;
p.len=1;
p.a[1]=④;
bign ans,now,t,kt=n,f,mmm=n;
cpy(ans,p);cpy(now,n);cpy(kt,n);cpy(mmm,n);
for(int i=1;i<=k;i++){
cpy(kt,mmm);cpy(f,ans);cpy(mmm,p);
int flag=0;
if(i==1)BBB(now,kt);
for(int j=1;j<=10;j++)
{
BBB(mmm,kt);
if(⑤){
flag=1;
break;
}
BBB(now,kt);
AAA(ans,f);
}
if(!flag){
cout<<"-1";return 0;
}
}
out(ans);
return 0;
}
- ① 处应填( )。
{{ select(35) }}
bign xbign &xbign x[]bign *x
- ② 处应填( )。
{{ select(36) }}
x.a[x.len-i]x.a[x.len/2-i]x.a[x.len/2-i+1]x.a[x.len-i+1]
- ③ 处应填( )。
{{ select(37) }}
i+j-1i+jiz.len-i-j
- ④ 处应填( )。
{{ select(38) }}
01k-1
- ⑤ 处应填( )。
{{ select(39) }}
now.a[i]!=n.a[i]now.a[i]!=n.a[j]now.a[i]==n.a[i]now.a[i]==n.a[j]
完善 2
二叉树是一种基本的数据结构,它要么为空,要么由根节点、左子树和右子树组成,同时左子树和右子树也分别是二叉树。
当一颗二叉树高度为 时,则共有 层。除 层外,其他各层的结点数都达到最大,且结点节点都在第 层时,这就是一个满二叉树。
现在,需要你用程序来绘制一棵二叉树,它由一颗满二叉树去掉若干结点而成。对于一颗满二叉树,我们需要按照以下要求绘制:
- 结点用小写字母
o表示。对于一个父亲结点,用/连接左子树,同样用\连接右子树。 - 定义
[i,j]为位于第 行第 列的某个字符。若[i,j]为/,那么[i-1,j+1]与[i+1,j-1]要么为o,要么为/。若[i,j]为\,那么[i-1,j-1]与[i+1,j+1]要么为o,要么为\。同样,若[i,j]为第 1~ 层的某个节点(即o),那么[i+1,j-1]为/,[i+1,j+1]为\。 - 对于第 层节点,也就是叶子结点,若两个属于同一个父亲,那么它们之间由 3 由 3 个空格隔开;若两个结点相邻但不属于同一个父亲,那么它们之间由 1 个空格隔开。第 层左数第 1 个节点之前没有空格。
最后需要在一颗绘制好的满二叉树上删除 个结点(包括它的左右子树,以及与父亲的连接),原有的字符用空格替换。
输入的第 1 行包含 2 个正整数 和 ,为需要绘制的二叉树层数已经从 层满二叉树中删除的结点数。接下来 行,每行两个正整数,表示第 层第 个结点需要被删除。
例如,输入:
4 0
输出:

输入:
4 3
3 2
4 1
3 4
输出:

提示:关于树枝长度的规律:
| 层数 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
树枝长 len |
1 | 2 | 5 | 11 | 23 |
| 规律 |
试补全程序:
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const int N = 3100;
int len[20],m,n,pos[20],h[20];
char a[N][N];
void prepare(){
int sum = 1;
len[1] = 1;pos[1] = 1;
FOR(i,2,m) {
len[i] = ①;
sum += len[i];
pos[i] = len[i] + 1;
}
h[m] = 1;
for(int i = m-1; i ;i --)
h[i] = h[i+1]+len[i]+1;
memset(a,' ',sizeof(a));
}
void draw(int x,int y,int depth){
a[x][y] = 'o';
if(②) return;
int lx = x+1,ly = y-1,rx = x+1,ry = y+1;
FOR(i,1,len[depth-1]){
a[lx][ly] = '/';
a[rx][ry] = '\\';
lx = lx+1,ly = ly-1,rx = rx+1,ry = ry+1;
}
draw(lx,ly,depth-1);
draw(rx,ry,depth-1);
}
void destroy(int x,int y){
a[x][y] = ' ';
if(a[x-1][y-1] == '\\')destroy(x-1,y-1);
③;
if(a[x+1][y-1] == '/' || a[x+1][y-1] == 'o')
destroy(x+1,y-1);
if(a[x+1][y+1] == '\\' || a[x+1][y+1] == 'o')
destroy(x+1,y+1);
}
void print(){
int height = h[1];
int width = 6 * (1<<(m-1));
FOR(i,1,height){
FOR(j,1,width)
printf("%c",a[i][j]);
printf("\n");
}
}
int main(){
cin >> m >> n;
prepare();
draw(④);
while(n--){
int i,j;
cin>>i>>j;
if(i > 10) continue;
int x = h[⑤],y;
if(i == m){
if(j & 1) y = pos[1] + j/2*6;
else y = pos[1] + j/2*6 - 2;
}
else
y = pos[⑤] + (j-1) * (2 * len[⑤] + 2);
destroy(x,y);
}
print();
return 0;
}
- ① 处应填( )。
{{ select(40) }}
ilen[i-1]+1len[i-1]+isum+i-1
- ② 处应填( )。
{{ select(41) }}
depth==0depth==1x==0x==y
- ③ 处应填( )。
{{ select(42) }}
if(a[x-1][y-1] == '\\')destroy(x-1,y-1);if(a[x-1][y-1] == '/')destroy(x-1,y-1);if(a[x-1][y+1] == '/')destroy(x-1,y+1);if(a[x-1][y+1] == '\\')destroy(x-1,y+1);
- ④ 处应填( )。
{{ select(43) }}
1,pos[m],m1,pos[m],11,pos[1],m1,pos[1],1
- ⑤ 处应填( )。
{{ select(44) }}
im-im+1-im-1+i