选择题
T5. 完全二叉树共有 2 × N − 1 2\times N-1 2×N−1 个结点,则它的叶结点数是( N
)。
【解析】有 2 × N − 1 2\times N-1 2×N−1 个结点的完全二叉树,最后一个拥有孩子结点的父结点的编号为 ⌊ 2 N − 1 2 ⌋ = N − 1 \lfloor \frac{2N-1}{2}\rfloor=N-1 ⌊22N−1⌋=N−1,那么叶结点数 = 2 × N − 1 − ( N − 1 ) = N =2\times N - 1 - (N - 1) = N =2×N−1−(N−1)=N。
T16. 面向对象程序设计(Object-Oriented Programming)是一种程序设计的方法论,它将对象作为程序的基本单元,将数据和程序封装在对象中,以提高软件的重用性、灵活性和扩展性。下面关于面向对象程序设计的说法中,不正确的是( )。
【解析】选项:面向对象程序设计通常采用自顶向下设计方法进行设计,是错误的。程序设计的方法包括:结构化设计和面向对象设计方法。结构化的程序设计通常采用自顶向下的设计方法,逐步求精。可以说,是大问题化成小问题,逐个求解。
T17. 在 32 × 32 32\times32 32×32 点阵的“字库”中,汉字“北”与“京”的字模占用字节数之和是(256
)。
【解析】 在 32 × 32 32\times32 32×32
点阵的“字库”中,每个字模占用的字节数为: 32 × 32 ÷ 8 = 128 32\times32\div8=128 32×32÷8=128。汉字“北”与“京”的字模占用字节数之和是256
。
问题求解
T2. 书架上有 4 本不同的书 A、B、C、D。其中 A 和 B 是红皮的,C 和 D 是黑皮的。把这 4 本书摆在书架上,满足所有黑皮的书都排在一起的摆法有(12
)种。满足 A 必须比 C 靠左,所有红皮的书要摆放在一起,所有黑皮的书要摆放在一起,共有(4
)种摆法。
【解析】
- 第一问满足所有黑皮的书都排在一起,可以使用捆绑和插空法,A、B排列后有3个空,将C、D排列后插入即可,答案为: P 2 2 × P 2 2 × C 3 1 = 12 P_2^2\times P_2^2\times C_3^1=12 P22×P22×C31=12
- 第二问,红皮的书要摆放在一起、黑皮的书要摆放在一起,使用捆绑法,即先将A、B捆绑排列,C、D捆绑排列,然后再将两个整体排列,此时A 必须比 C 靠左的排列占了一半,所以答案为: P 2 2 × P 2 2 × 2 ÷ 2 = 4 P_2^2\times P_2^2\times 2\div2=4 P22×P22×2÷2=4
阅读程序
T4.
#include<iostream>
#include<cstring>
using namespace std;
#define MAX 100
void solve(char first[], int spos_f, int epos_f, char mid[], int spos_m, int epos_m)
{
int i, root_m;
if (spos_f > epos_f)
return;
for (i = spos_m; i <= epos_m; i++)
if (first[spos_f] == mid[i])
{
root_m = i;
break;
}
solve(first, spos_f + 1, spos_f + (root_m - spos_m), mid, spos_m, root_m - 1);
solve(first, spos_f + (root_m - spos_m) + 1, epos_f, mid, root_m + 1, epos_m);
cout << first[spos_f];
}
int main()
{
char first[MAX], mid[MAX];
int len;
cin >> len;
cin >> first >> mid;
solve(first, 0, len - 1, mid , 0, len - 1);
cout << endl;
return 0;
}
输入:
7
ABDCEGF
BDAGECF
输出:
DBGEFCA
【解析】输入二叉树的先根遍历序列和后根遍历序列,求后根遍历序列。
完善程序
T1.(字符串替换)给定一个字符串 S(S 仅包含大小写字母),下面的程序将 S 中的每个字母用规定的字母替换,并输出 S 经过替换后的结果。程序的输入是两个字符串,第一个字符串是给定的字符串 S,第二个字符串 S’ 由 26 个字母组成,它是 a−z 的任一排列,大小写不定,S’ 规定了每个字母对应的替换字母:S 中的第一个字母是字母 A 和 a 的替换字母,即 S 中的 A 用该字母的大写替换, S 中的 a 用该字母的小写替换;S’ 中的第二个字母是字母 B 和 b 的替换字母,即 S 中的 B 用该字母的大写替换,S 中的 b 用该字母的小写替换;……以此类推。
#include <iostream>
#include <string.h>
char change[26], str[5000];
using namespace std;
void CheckChangeRule()
{
int i;
for (i = 0;i < 26; i++)
{
if ( ① )
change[i] -= 'A' - 'a';
}
}
void ChangeString()
{
int i;
for (i = 0;i <strlen(str); i++)
{
if ( ② )
str[i] = change[str[i] - 'A'] -'a' + 'A';
else
③
}
}
int main()
{
int i;
cin >> str ;
cin >> change;
CheckChangeRule();
④
cout << str << endl;
return 0;
}
【解析】
- 空①,函数
CheckChangeRule()
将字符数组change
中所有大写字符转换为小写。如果change[i]
为大写字符,需要转换为小写,此空应填change[i]>='A' && change[i]<='Z'
。- 空②,如果要替换的是大写字符,即
str[i]>='A' && str[i]<='Z'
。- 空③,替换小写字符,
str[i] = change[str[i] - 'a'];
- 空④,调用函数
ChangeString()
进行替换。
T2. (找第 k 大的数)给定一个长度为 1,000,000 的无序正整数序列, 以及另一个数 n ( 1 ≤ n ≤ 1000000 1\le n\le1000000 1≤n≤1000000), 然后以类似快速排序的方法找到序列中第 n 大的数(关于第 n 大的数:例如序列 {1,2,3,4,5,6} 中第 3 大的数是 4)。
#include <iostream>
using namespace std;
int a[1000001],n,ans = -1;
void swap(int &a,int &b)
{
int c;
c = a; a = b; b = c;
}
int FindKth(int left, int right, int n)
{
int tmp, value, i, j;
if (left == right) return left;
tmp = rand()% (right - left) + left;
swap(a[tmp], a[left]);
value = ①
i = left;
j = right;
while (i < j)
{
while (i < j && ②) j --;
if (i < j) {
a[i] = a[j]; i++; } else break;
while (i < j && ③) i++;
if (i < j) {
a[j] = a[i]; j--; } else break;
}
④
if (i < n) return FindKth( ⑤ );
if (i > n) return ⑥
return i;
}
int main()
{
int i;
int m = 1000000;
for (i = 1; i <= m; i++)
cin >> a[i];
cin >> n;
ans = FindKth(1, m, n);
cout << a[ans];
return 0;
}
【解析】通过快速排序的思想,查找第
n
大的数。根据输出cout << a[ans];
,可以确定是将序列按照从大到小的顺序进行排列。函数FindKth()
将数组分成两部分,左边由大于等于value
的数组成,右边由小于value
的数组成。
- 空①,设置基准值
value = a[left];
- 空②,找到右边第一个大于等于
value
的位置,将该位置的数放到i
位置,此空应填a[j]<value
。- 空③,找到左边第一个小于等于
value
的位置,将该位置的数放到j
位置,此空应填a[j]>value
。- 空④,将
value
放入到i
位置,将数组分为两部分,此空应填a[i]=value;
- 空⑤,如果
i<n
,到右边部分继续查找第n
大的数,此空应填i+1,rigth,n
- 空⑥,如果
i>n
,到左边部分继续查找第n
大的数,此空应填FindKth(left,i-1,n)