目录
0、基础知识点
一、单选题
二、多选题
三、判断题
0、基础知识点
(1)常见时间复杂度与公式:
汉诺塔:T(n)=O(2^n)
全排列:T(n)=O(n!)
整数划分:
正整数n的划分:p(n)=q(n,n)
分治:
二分查找:T(n)=O(logn)
归并排序:T(n)=O(nlogn)
快速排序:T(n)=O(nlogn)
(2)使用动态规划求解
数字三角形:T(n)=O(n^2)
最大字段和:T(n)=O(n)
最长递增子序列:T(n)=O(n)
0-1背包:T(n)=O(nc) S(n)=O(nc) 【c为背包容量】
(3)使用贪心
矩阵连乘:T(n)=O(n^3) S(n)=O(n^2)
最长公共子序列:T(n)=O(m^n) S(n)=O(m^n)
活动安排:T(n)=O(nlogn)
部分背包:T(n)=O(nlogn)
最优装载:T(n)=O(nlogn)
Dijkstra:T(n)=O(v^2)
prim:T(n)=O(v^2)【稠密图】
kruskal:T(n)=O(ElogE)【稀疏图】
图的m着色问题:T(n)=O(m^n)
n后问题:T(n)=O(n^n)
一、单选题
1、我们可以使用()来直观形象地描述算法,有助于更好地理解算法。
A 自然语言
B 高级程序设计语言
C 程序流程图 (直观形象)
D 伪代码 (更简单易懂,容易修改,易于转成程序)
2、如果程序通过,在OJ中将提示()。
A Time Limit Exceeded
B Wrong Answer
C Presentation Error
D Accepted
3、算法分析的目的是( )。
A 找出数据结构的合理性
B 找出算法中输入和输出之间的关系
C 分析算法的易懂性和可靠性
D 分析算法的效率以求改进
4、函数f(n)=log(n^3)+n^(1/2)最合适的阶为()。logn<n^(1/2)
A O(n^3)
B O(n^(1/2))
C O(logn)
D O(n)
5、函数F(n)=n^3+3n^2+nlogn+10n+100的渐进性态为()。
A O(10n)
B O(nlogn)
C O(n^2)
D O(n^3)
6、递归的应用场景不包括( )。
A 问题的定义是递归的
B 采用的数据结构是递归的
C 问题的求解方法是递归的
D 问题规模较大且不能用循环实现
7、一只青蛙一次可以跳上1级台阶,也可以跳上2级。青蛙跳上第6级台阶有几种跳法?
A 5
B 12
C 13
D 21
8、对于f(n)=4n+1,下列说法错误的是()。
A f(n)= (1)
B f(n)= (n)
C f(n)=O(n^2)
D f(n)= (n^3)
9、递归的优点不包括()。
A 结构清晰
B 可读性强
C 容易证明算法的正确性
D 运行效率高
10、一个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶、3阶。请问当n=6时,小孩有多少种上楼的方式?
A 12
B 13
C 24
D 32
11、以下关于算法时间复杂性渐进表示法错误的一项是()。
A 2n^2+nlogn+n=O(n^2)
B n2+(n^2)logn+n= (n^2)
C 100n^2= (n^2)
D nlogn^2= (n^2)
12、8个圆盘的汉诺塔最少需要移动多少步才能够全部移完? (2^n )-1
A 15
B 16
C 255
D 256
13、如下代码的时间复杂度为T(n)=()。
int func(int n)
{
int i=1,k=0;
while(i<=n){
k++;
i=i*5;
return k;
}
A O(n)
B O(logn)
C O(n/5)
D O(n^5)
14、一只青蛙一次可以跳上1级台阶,也可以跳上2级,也可以跳上3级......它也能够跳上n级台阶。那么该青蛙跳上一个6级的台阶总共有多少种跳法? 这种情况(可以跳1到n级台阶)可以用公式 2^(n-1)
A 12
B 13
C 16
D 32
15、5个不同的元素有多少种全排列? n!
A 24
B 25
C 120
D 3125
16、在三根柱子的汉诺塔问题中,如果一共有n个圆盘,那么最上层圆盘(最小的圆盘)的最少移动次数为( )。
A 1
B 2^(n-1)
C 2^n-1
D 2^n
17、代码填空【使用递归求数字全排列问题】:
void perm(int list, int k,int n){
if(_ (1)_ ){
for(int i=0; i<=n; i++) {
printf("%d", list[il);
}
printf("\n");
}
int t;
for(int i=k; i<=n;i++){
{t=list[k];list[k]=list[i];list[i]=t;}
(2) ;
{t=list[i];list[i]=list[k];list[k]=t;}
}
}
A (1) k==n (2) perm(list,k-1,n)
B (1) k==n (2) perm(list, k+1,n)
C (1)k==1 (2) perm(list, k-1, n)
D (1)k==1 (2) perm(list, k+1,n)
18、在整数划分问题中,将n的最大加数不大于m的划分个数记作q(n,m),则以下表达式有误的一项是:
A 当n=1或m=1时,q(n,m)=1
B 当n<m时,q(n,m)=q(m,m)
C 当n=m时,q(n,m)=1+q(n,n-1)
D 当n>m>1时,q(nm)=q(n,m-1)+q(n-m, m)
19、给定递归公式T(n)=4T(n/2)+O(n),由主定理可以得知T(n)=( )。
A O(logn)
B O(nlogn)
C O(n^2)
D O(n)
20、假设有一个包含1500个名字的有序列表,现使用二分查找在其中查找一个名字,最多需要几步才能找到? 2^10=1024
A 8
B 9
C 11
D 12
21、给定递归公式T(n)=4T(n/4)+O(1),由主定理可以得知T(n)=( )。
A O(logn)
B O(nlogn)
C O(n^2)
D O(n)
22、给定递归公式T(n)=2T(n/2)+O(n),由主定理可以得知T(n)=( )。
A O(logn)
B O(n)
C O(nlogn)
D O(n^2)
23、使用快速排序对以下数据进行升序排序:
44, 75, 23, 43, 55, 12, 64, 77, 33
现在以第1个数作为分区基准,则第1趟分区之后的结果为:
A 33, 23, 43, 12, 44, 75, 64, 77, 55
B 12,23, 33, 43, 44, 55,64, 75,77
C 23, 12, 33, 43, 44, 75, 55, 64, 77
D 43, 33, 12, 23, 44, 75, 55, 64, 77
24、使用第一个元素作为划分基准,如果需要将数组由小到大排序,那么对于整数数组
{6,5,4,3,2,1},第一趟分区之后的结果为( )。
A {6,5, 4, 3,2, 1}
B {1,5,4, 3,2,6}
C {1,2, 3, 4,5,6}
D {5,4, 3, 2, 1, 6}
25、代码填空【快速排序的分区函数:以第1个元素为基准元素,由小到大排序】
int swap(int a[ ], int i, int j) {
int temp = ali];a[i] =alij];ali]=temp;
}
int partition(int a[ ], int p, int q) {
int x = a[p];
int i=p, j;
for(j=p+1;j<=q;j++){
if(alj]<=x){
i++;
(1)_____
}
}
(2)_____
return i;
}
A (1) swap(a, i,j) (2) swap(a, p, i)
B(1) swap(a, q, j) (2) swap(a,p,q)
C(1) swap(a, i, j) (2) swap(a, i,q)
D(1) swap(a, q, j) (2) swap(a, p,q)
26、为了避免快速排序出现最坏情况,在分区函数中可以采用以下哪种方式来选择划分基准?
A 选取子序列的第一个元素作为划分基准
B 选取子序列的最后一个元素作为划分基
C 选取子序列最中间的元素作为划分基准
D 随机选取一个元素作为划分基准
27、已知rand()函数可以随机生成一个非负整数k,现在需要通过k得到一个(m,n]之间的正整数a,可以是n但不能是m。则以下表达式正确的是()。
A a =k %(n-m+1)+m;
B a=k %(n-m+1)+ m +1;
C a=k%(n-m)+m+1;
D a=k%(n-m)+m;
28、关于在无序序列a[s..t]中查找第k小元素的过程,以下有误的一项是( )。
A 如果s=t,返回a[s]
B 如果s!=t,将以基准为中心将其划分为B a[s..i]和a[i+1..t],a[s..i]中所有元素均小于等于a[i],a[i+1..t]中所有元素均大于a[i]
C 统计小于等于alil的元素个数:j=i-s+1,如果i>=k,则递归在a[s..i]中寻找第k小元素
D 统计小于等于ali的元素个数:i=i-s+1,如果j<k,则递归在a[i+1..t]中寻找第k小元素
29、在棋盘覆盖问题中,如果(tr,tc)表示棋盘左上角的坐标位置,(dr,dc)表示特殊方格的坐标位置,s为分割之后小棋盘的边长。如何判断特殊方格是否在右上部分的小棋盘中,以下条件判断语句正确的是( )。
A dr<tr+s&&dc>=tc+s
B dr>=tr+s&&dc<tc+s
C dr<tr+s&&dc<tc+s
D dr>=tr+s&&dc >=tc+s
30、采用随机化改进后,查找一个无序序列的第k小元素或第k大元素的平均时间复杂度为
A O(logn)
B O(n)
C O(nlogn)
D O(n^2)
31、代码填空:【归并排序的合并函数:SR为原始数组,TRⅡ为目标数组,由小到大排序】
void merge (int SR[ ], int TR[ ], int s, int m, int t){
int i=s, i=m+1, k=s;
while( _(1)_ ){
if (SR[i]<=SR[j]) TR[k++]=SR[i++];
else TR[k++]=SR[j++];
}
while (_ (2)_ )TR[k++]=SR[i++];
while( _(3) _) TR[k++]=SR[j++];
}
A (1)i>=m llj>=t
(2) i>=m
(3) j>=t
B (1) i<=m ll j<=t
(2)i<=m
(3) j<=t
C (1) i>=m &&j>=t
(2)i>=m
(3)j>=t
D (1)i<=m &&j<=t
(2)i<=m
(3)j<=t
32、对于整数数组{8,1,4,3,2,5,7,6},如果使用归并排序将数组元素按由小到大排序,那么第二趟归并之后的结果是()。
A 1, 8,3, 4, 2,5,6,7
B 1, 3, 4, 8, 2,5,6,7
C 1, 2, 3, 4, 5,6, 7, 8
D 5,6, 7, 8, 1, 2, 3,4
33、以下哪段代码可以将一个长度为n的正整数X分割为两个长度为n/2的正整数A和B (n=2^k),并且A为高n/2位,B为低n/2位?
A
long A = (X % (long)pow(10, n / 2));
long B=(long)(X/pow(10,n /2));
B
long A =(long)(X / pow(10, n /2));
long B =(X % (long)pow(10, n / 2));
C
long A=(X%(long)pow(10, n)/2)
long B=(long)(X/ pow(10,n)/2);
D
long A = (long)(X / pow(10, n) /2);
long B=(X%(long)pow(10, n)/2);
34、Strassen矩阵乘法的时间复杂度为()。
A T(n)=O(n^3)
B T(n)=O(n^2)
C T(n)= (n^2.81)
D T(n)= (n^1.59)
35、能够使用动态规划算法来求解的问题,需要具备的基本要素包括( )。
A 独立子问题和最优子结构
B 平衡子问题和局部最优化
C 平衡子问题和重复子问题
D 重复子问题和最优子结构
36、在数字三角形问题中,每一个位置下一个可以到达的位置为其下方的位置和右下方的位置,如果需要得到最小路径和,已知plil[il表示(i,i)到达最后一层的最小路径和。当1<=i<n时,以下表达式正确的是( )。
A p[il[j] =max{p[i+1][j], p[i+1][j+1]}+a [i][j]
B p[i][j] =max{p[i+1][j-1],p[i+1][j]}+a[i][j]
C p[i][j] =min{p[i+1][j],p[i+1][j+1]}+a[i][j]
D p[i][j]= min{p[i+1][j-1],p[i+1][j]}+a[i][j]
37、使用动态规划算法求解最长公共子序列问题,如果使用数组c[i][i]记录序列x[i]和序列ylil的最长公共子序列的长度,则以下表达式错误的一项是( )。
A 如果i=0或者i=0,则c[i][i]=0
B 如果i>0,j>0且x[i]=y[i],则c[i][j]=c[i-1] [j-1]+1
C 如果i>0,j>0且x[i]!=y[i],则c[i][j]=max{c[i] [j-1],c[i-1] [j]}
D 如果i>0,j>0且x[i]!=y[i],则c[i][j]=max{c[i] [j-1],c[i-1] [j]}+1
38、使用动态规划算法求解数字三角形问题的时间复杂度是( )。
A O(2^n)
B O(n^2)
C O(n^3)
D O(n)
39、给定两个字符序列“programming”和
“contest”,它们的最长公共子序列的长度为()。
A 1
B 2
C 3
D 4
40、给定两个字符序列“ABCFBC”和“ABFCAB”,它们的最长公共子序列的长度为( )。
A 2
B 3
C 4
D 5
41、使用动态规划算法求两条长度分别为m和n的序列的最长公共子序列,其时间复杂度为
A O(n^2)
B O(m^n)
C O(nlogm)
D O(n*m)
42、代码选择填空: (构造最长公共子序列的函数,其中b[i][i]用于记录c[i][i]的取值方向,如果c[i][j]=c[i-1][j-1]+1则b[i][j]=1,如果c[i-1][j]>=c[i][i-1]则b[[i][j]=2,如果c[i-1][j]<c[i][j-1]则b[i][j]3。)
void Ics(int i, int j, char x, int b){
if (i==0 ll i==0) return;
if (b[i][j]==1){
_(1)_
System.out.print(x[i]);
}
else if (b[i][i]==2) _(2)_
else _(3)_
A
(1)Ics(i,j,x,b)
(2)Ics(i-1, j,x, b)
(3) Ics(i, j-1, x, b)
B
(1)Ics(i, j,x,b)
(2) Ics(i, j-1, x, b)
(3) Ics(i-1, j, x, b)
C
(1) Ics(i-1, j-1, x, b)
(2)Ics(i, j-1, x,b)
(3)Ics(i-1, j,x,b)
D
(1) lcs(i-1, j-1, x, b)
(2) lcs(i-1, j, x, b)
(3) Ics(i, j-1, x, b)
43、代码选择:使用备忘录法求解最长公共子序列问题。
int Ics(char ×[ ], char y[ ], int i, int j)
{
if((i== 0)11(j == 0)){
c[i][j]=0; return 0;
}
if(c[i][j]==-1){
if(x[i] ==y[j])
c[il[j]= _(1)_
else
c[i][j]=_ (2)_
}
return c[il[j];
}
A
(1) Ics(x, y, i-1, j-1)+1
(2) max(lcs(x, y, i-1, j), Ics(x, y, i, j-1))
B
(1)Ics(x, y, i, j)+1
(2) max(lcs(x, y, i-1, j), Ics(x, y, i, j-1))
C
(1)Ics(x, y, i, j)+1
(2) min(Ics(x, y, i-1, j), Ics(x, y, i, j-1))
D
(1) Ics(x, y, i-1, j-1) + 1
(2) min(Ics(x, y, i-1, j), Ics(x, y, i, j-1))
44、使用动态规划算法求最大子段和的时间复杂度为()。
A O(logn)
B O(n)
C O(nlogn)
D O(2^n)
45、代码选择填空:(求解最大子段和的函数,其中b[i]表示以ali]作为最后一个元素的最大子段和)
void solve() {
b[0]=a[0];
maxSum=b[0];
for(int j=1;j<n;j++) {
if(b[j-1]>0)
(1)_
else
(2).
if(b[j]>maxSum)
maxSum=b[j];
}
}
A
(1)b[j]=b[j-1]+a[j];
(2)b[j]=a[j];
B
(1)b[j]=a[j];
(2)b[j]=blj-1]+a[j];
C
(1) b[i]=b[j-1]+a[j-1];
(2) b[j]=a[j-1];
D
(1) b[j]= a[j-1];
(2) b[j]= b[j-1]+a[j-1];
46、整数序列[4,-3,5,-2,-1,2,5,-2]的最大子段和为( )。
A 7
B 8
C 9
D 10
47、序列(1,7,3,4,9,2,3)的最长递增子序列的长度为( )。A 1
B 2
C 3
D 4
48、如果物品的数量为n,背包的容量为c,则使用动态规划算法求解0-1背包问题的时间复杂度为()。
A O(nc)
B O(n+c)
C O(n^c)
D O(2^n)
49、代码选择填空:使用动态规划算法求解0-1背包问题(从第n个物品到第1个物品)。
void solve(int v[ ],int w[ ].int c.int n, int m[ ][11]){
//填写表格最后一行(第n行),代码省略for (int i=n-1;i>=1;i--){ //从第n-1行填至第1行
int jMax=min(w[i]-1,c);
for (int j=0;j<=jMax;j++) { //当0=<j<w[i]
m[il[j]=_(1)_
}
for (int j=w[i];j<=c;j++){ //当j>=w[n]
m[il[j]= _(2)_
}
}
A
(1) m[i+1][j]
(2)max(m[i+1][i],m[i+1][j-w[i]])
B
(1)m[i+1][j]+v[i]
(2) max(m[i+1][,m[i+1][j-w[i]])
C
(1) m[i+1][j]
(2) max(m[i+1][i], m[i+1][i-w[i]]+v[i])
D
(1)m[i+1][j]+v[i]
(2)max(m[i+1][j],m[i+1][j-w[il]+v[i])
50、代码选择填空:使用动态规划法求解最长递增子序列问题。
int ,a[105],b[105], maxLen, max;
void solve() {
b[1]=1;
max= b[1]://max用于存储最长递增子序列的长度
for (inti=2;i<=n;i++){//分阶段
maxLen = 0;
for (intj=i-1;j>=1;j--){//枚举每个状态
if ( _(1)_){
maxLen = b[j];
}
}
b[i]= _(2)_;
if(b[i]>max){
_(3)_
}
}
}
A
(1) a[i]>a[i]&&b[i]>maxLen
(2) maxLen
(3) max = b[i]
B
(1) a[i]<a[i]&&b[i]>maxLen
(2) maxLen+1
(3) max = b[i]
C
(1)a[i]<a[i]&&b[i]<maxLen
(2)maxLen
(3)max=b[i] +1
D
(1)a[i]>a[i]&&b[j]<maxLen
(2)maxLen +1
(3)max=b[i]
51、如果从最后一个物品开始逐一尝试将物品装入背包,数组m[i][j]存储背包容量为j,可选择物品为i,i+1,....n时0-1背包问题的最优值。则0-1背包问题的最优解为( )。【n为物品数量,c为背包容量】
A m[n][c]
B m[1][c]
C m[1][1]
D m[n][1]
52、输入a数组{1,7.3.5},数组下标从1开始,用b数组存储对应的最长递增子序列长度。当i=3时,b[i]=( )。
A 1
B 2
C 3
D 4
53、代码选择填空:使用贪心算法求解部分背包问题。
void knapsack(){
value=0; //初始化最大价值为0
double weight=W;//背包中能够装入的剩余重量
memset(x,0,sizeof(x));//初始化x向量int i=1;
while(i<=n&&A[i].w<=weight){
x[i]=1;
weight= _(1)_
value = _(2)_
i++;
}
if(i<=n&&weight>0){
x[i]=_ (3)_
value = _(4)_
}
}
A
(1)weight+A[i].w
(2) value-A[i].v
(3)A[i].w
(4) value+x[i]*A[i].v
B
(1) weight+A[i].w
(2) value-A[i].v
(3)weight/A[i].w
(4) value+A[i].v
C
(1)weight-A[i].w
(2) value+A[i].v
(3)A[i].w
(4) value+A[i].v
D
(1) weight-A[i].wi
(2) value+A[i].v
(3) weight/A[i].w
(4) value+x[i]*A[i].v
54、如果m(i,j)是背包容量为j,可选择物品为1,2,...i-1,i时0-1背包问题的最优值,则以下描述有误的一项是()。
A当j>=w1时,m(1,j)=v1
B 当1<i<=n且i>=wi时,m(i,j)=max{m (i-1, i), m(i-1, j-wi) + vi}
C 当1<i<=n且0<=j<wi时,m(i,j)=m(i- 1,j-wi) +vi
D m(n,c)为所求最优值(n为物品数量,c为背包容量)
55、关于部分背包问题的描述,以下有误的一项是()。
A 部分背包问题允许将一个物品的一部分装入背包
B 对于无序的物品,部分背包问题的时间复杂度为 (nlogn)
C 部分背包问题使用贪心算法可以求得全局最优解
D 部分背包问题的主要计算量在于贪心选择过程
56、已知五个物品的重量分别为{10,20,30,40,50},价值分别为{20,30,66,40,60},背包容量为100,采用部分背包问题求解可以得到的最大价值为()。
A 156
B 160
C 164
D 166
57、在使用贪心算法求解活动安排问题的贪心选择函数中,以下()是需要补充的代码,//结构体:活动
struct Activity(
int sTime; //活动开始时间
int fTime;//活动结束时间
};
//贪心选择函数
int activitySelect(Activity activities[], int n) (
int j=0;
int activityCount=1;
for(inti=1;i<n;i++){
if( ){
j=i;
activityCount++;
}
return activityCount;
}
A.activities[il.sTime>= activities[il.fTime
B.activities[i].sTime>= activities[j].fTime
C. activities[i].sTime> = activities[i].sTime
D.activities[il.fTime>= activities[i].fTime
58、()不能使用贪心算法来求解。
A.部分背包问题
B.活动安排问题
C.最优装载问题
D.矩阵连乘问题
59、并查集是一种()数据结构,用于处理一些不相交集合的合并及查询问题。
A.线性
B.树型
C.网状
D.二维
60、给定5个集装箱,它们的重量分别是3,4,5,2.1,已知船的装载量为10,该船最多可装载的集装箱数量是()个。
A.2
B.3
C.4
D.5
61、代码选择填空:并查集。
/*带路径压缩的查找*/
int find set(int x){
if(x!= pa[x])
pa[x]=_ (1)_
return pa[x];
}
/*按秩合并x,y所在的集合*/
void union set(int x, int y)(
x=find set(x);
y=find set(y);
if(x==y) return;
if(_ (2)_ )
pa[y]=x;
else {
pa[x]=y;
if(rank[x]==rank[y])
rank[y]++;
}
A.
(1) find_set(x)
(2) rank[x]<rank[y]
B.
(1) find _set(pa[x])
(2) rank[x]<rank[y]
C.
(1) find set(x)
(2) rank[x]> rank[y]
D.
(1) find set(pa[x])
(2) rank[x] > rank[y]
62、加权无向图G的顶点数为V,边数为E,则使用未经优化的Prim算法来求解图G的最小生成树的时间复杂度为().
A.O(VE)
B.O(VlogV)
C.O(V^2)
D.O(E^2)
63、使用Kruskal算法构造图G的最小生成树的时间复杂度为()。【V表示图G中顶点的数量,E表示图G中边的数量】
A.O(V^2)
B.O(VlogV)
C.O(E^2)
D.O(ElogE)
64、含有n个顶点的连通图的生成树含有()条边。
A.n(n+1)/2
B.n-1
C.n
D.2n
65、()是回溯法中为避免无效搜索采取的策略。
A.递归函数
B.剪枝函数
C.随机数函数
D.搜索函数
66、回溯法搜索解空间树是按照()的顺序。
A.广度优先遍历
B.深度优先遍历
C.层次优先遍历
D.随机遍历
67、4皇后问题的解的个数为()。
A.0
B.2
C.4
D.92
68、代码选择填空:使用回溯法求解图的m着色问题。
//二维数组graph[]、用于存储图,一维数组colors[]用于存储每个节点的颜色
int check(int t, int i) //剪枝函数
{
for(int j=1;j<t;j++)
{
if( (1)
return 0;
}
return 1;
}
void solve(int t){ //搜索函数
if(t>N)//算法搜索至叶子节点
//代码省略
else {
for(int i=1;i<=m;i++){
if(check(t,i)){
(2)
solve(t+1);
}
}
A.graph[t][j]==0||colors[i]==i
colors[i]=t
B.graph[t][j]==0||colors[j]==i
colors[t]=i
C.graph[t][j]==1&&colors[j]==i
colors[i]=t
B.graph[t][j]==0 colors[j]==i
colors[t]=i
C.graph[t][j]==1&&colors[j]==i
colors[i]=t
D.graph[t][j]==1&&colors[j]==i
colors[t]=i
69、代码选择填空:使用回溯法求解n后问题。
//搜索函数,二维数组A[N][N]用于存储皇后位置,一维数组MIk1、L[k1、RK1分别表示竖列、左斜线、右斜线是否放有皇后,有则值为1,否则值为0
int solve(int i) {
for(intj=0;j<N;j++){
if(_ (1) ){//安全检查
A[i][j]=i+1;//放皇后
Mj]=L[i+j]=R[i-j+N]=1
if(i==N-1){
//代码省略
}
else
(2)_ ;//试探下一行
A[i][j]=0;//去皇后
M(jl=L[i+j]=R[i-j+N]=0;
}
return count;
}
}
A.
(1)!M[i]&&!L[i+j]&&!R[i-j+N]
(2) solve(j+1)
B.
(1)!M[i]l|!L[i+j]ll!R[i-j+N]
(2)solve(j+1)
C.
(1)!M[j]&&!L[i+j]&&!R[i-j+N]
(2) solve(i+1)
D.
(1)!M[j]l!L[i+j]ll!R[i-j+N]
(2) solve(i+1)
70、任何一张地图只用( )种颜色就能使具有共同边界的国家着上不同的颜色。
A.3
B.4
C.5
D.6
二、多选题
1、算法的复杂性分析主要包括()。
A 时间复杂性分析
B 数据结构复杂性分析
C 空间复杂性分析
D 代码复杂性分析
2、算法具有以下哪些性质?
A 至少有一个输入
B 至少有一个输出
C 组成算法的每条指令清晰且无歧义
D 算法中每条指令的执行次数有限
E 算法中执行每条指令的时间有限
3、递归的要素包括( )。
A 递归开始条件
B 递归结束条件
C 递归表达式
D 递归深度
E 递归类型
4、关于二分查找的设计思想,以下说法正确的是()。
A 待查找元素key首先和最中间的值a[mid]进行比较
B 如果key等于a[mid],则返回mid
C如果key小于a[mid],则在降序序列的前半部分继续查找
D如果key大于almid],则在降序序列的后半部分继续查找
E如果没有找到待查找元素,可以返回一个不存在的下标值,例如-1
5、关于归并排序的描述,( )是正确的。
A 归并排序的平均时间复杂度为O(nlogn)
B 归并排序的最坏时间复杂度为O(n^2)
C 归并排序的空间复杂度为 O(n)
D 归并排序的空间复杂度为 O(1)
E 归并排序是一种稳定的排序
6、下列关于动态规划算法与分治法的说法正确的是()。
A动态规划算法与分治法类似,基本思想是将待求解问题分解成若干个子问题
B 动态规划算法经分解得到的子问题往往是独立的,且不存在重复子问题
C 分治算法经分解得到的子问题往往是独立的
D 动态规划算法经分解得到的子问题往往不是独立的,有些子问题被重复计算多次
7、关于备忘录法,以下说法正确的是()。
A 备忘录法的算法结构与直接递归的结构相同
B 引入一个备忘录用于存储已求解过的子问题的解
C 采用自顶向下分解的结构来求解问题
D 备忘录法又称为填表法
8、关于最长公共子序列问题,以下说法正确的是()。
A两个序列的最长公共子序列包含了这两个序列前缀的最长公共子序列
B 空序列和一条非空序列的最长公共子序列的长度为0
C 如果两个序列的最后一个元素相同,则它们的最长公共子序列长度为去掉最后一个元素后,两个剩余序列的最长公共子序列长度加1
D 两个序列的最长公共子序列可能不唯一
9、下列关于使用动态规划算法求解最长公共子序列问题的优化方案,正确的是( )。
A 可进一步省略数组b,数组元素c[i][i]的值仅由c[i-1][i],c[i-1][j-1],c[i][i-1]这3个数组元素的值所确定
B 在算法中,b数组一定不能省略
C 如果只需要计算最长公共子序列的长度,通过引入滚动数组则算法的空间需求可大大减少
D 在构造最优解时,可以通过引入滚动数组来大大减少空间需求
10、关于贪心算法,以下说法正确的是( )。
A 部分背包问题可以使用贪心算法求解
B 0-1背包问题可以使用贪心算法找到最优解
C 贪心算法在每一步选择中都采取最好或者最优 (最有利)的选择策略
D 贪心算法可以用于求解各类问题的最优解
E 贪心算法可以用于求解任意面值的找硬币问题
11、下列关于贪心算法与动态规划算法说法正确的是()。
A 贪心算法与动态规划算法的主要区别是贪心算法要求问题具有贪心选择性质
B 贪心算法与动态规划算法求解的问题都具备最优子结构性质
C 贪心算法与动态规划算法的主要区别是动态规划算法要求问题具有贪心选择性质
D 贪心算法与动态规划算法求解的问题都具有重复子问题性质
12、为了提高根结点的查询效率,在并查集中采用了()的优化策略。
A.按秩合并
B.按权排序
C.路径压缩
D.状态压缩
13、关于活动安排问题,以下说法正确的是( )。
A.活动安排问题的贪心选择意义在于使剩余的可安排时间段极大化,以便安排尽可能多的相容活动,
B.算法每次总是选择具有最早完成时间的相容活动加入集合中。
C.在输入活动无序的情况下,算法的时间复杂度为O(n)。
D.对于活动安排问题,贪心算法能求得的整体最优解,即它最终所确定的相容活动集合的规模最大。
14、在Prim算法的松弛操作中,对于点k,如果((!used[k])&&(G[i][k]<lowcost[k]))为真,则()。
A.将k到j的距离作为新的k到S之间的距离
B.将j作为k在S中的最近邻点
C. lowcost[k]=G[j][k]
D.closeset[k]=j
15、关于Prim算法和Kruskal算法,以下说法正确的是()、
A.Prim算法适用于求稠密图的最小生成树
B.Prim算法适用于求稀疏图的最小生成树
C. Kruskal算法适用于求稠密图的最小生成树
D.Kruskal算法适用于求稀疏图的最小生成树
E.Kruskal算法通过使用并查集来高效地构造图的最小生成树
F.Prim算法是一种基于贪心思想求解加权无向图的最小生成树的算法
16、关于Prim算法中的数据结构,以下说法正确的是( )。
A.使用数组lowcost[n1记录不在S中的顶点到S的最短距离
B.使用数组closesetIn1记录不在S中的顶点在S中的最近邻接点
C.使用数组lowcost[n]记录不在S中的顶点到第一个顶点的最短距离
D.使用数组used[n]标记顶点是否被访问
17、关于Dijkstra算法,以下说法正确的是()。
A.Diikstra算法既可以用于求解单源最短路径问题,也可以用于求解单终点最短路径问题
B.有向图和无向图都可以使用Dijkstra算法来求单源最短路径
C.在Dijkstra算法中,通过松弛操作来更新源点到其他顶点的距离
D.Diikstra算法可以用于求解各种图的单源最短路径问题,在图中,每一条边的权重可正可负
18、关于Prim算法和Dijkstra算法,以下说法正确的是()。
A.两个算法都是贪心算法的经典实例
B.两个算法都需要引入一个数组用于记录一个点是否被访问过
C.两个算法在不优化时的时间复杂度都为O(V^2),V表示顶点的个数
D.两个算法都包含了松弛操作,在松弛时需要对相应的数据结构进行更新
19、关于Dijkstra算法中的数据结构,以下说法正确的是( )
A.需要引入一个usedf数组用于记录一个点是否已访问过
B.需要引入一个disfl数组用于保存源点到其他点的最短路径值一
C.如果源点到某一个点i没有直接的边相连,则disfi1的初始值为无穷大
D.如果源点到某一个点i之间有一条边,则disi的初始值为这条边的权重
20、Dijkstra算法可用于求解()。
A.单源最短路径问题
B.单终点最短路径问题
C.单对顶点最短路径问题
D.每对顶点间最短路径问题
21、回溯法可以用于()
A.求一个问题的所有解
B.求一个问题的最优解
C.求一个问题的任一解
D.判断一个问题是否有解
22、关于马的遍历问题,以下说法正确的是()。
A.在遍历过程中的剪枝条件为:不能走出边界,且同一条路径中每个点只经过一次。
B.使用一个变量dep记录递归深度,初始值为1,每遍历一个点,dep加1;当dep=n*m时,即找到一组可行解。
C.马的遍历问题要求找出全部可能的解,因此在更换遍历方向时需要将一些先前已经走过的位置设为未经过。
D.在马的遍历问题中,可以引入方向引导数组来记录马在行走过程中下标的改变。
23、在马的遍历问题中,如果马的初始位置为(x.v),在不考虑重复和出界的情况下。()是下一个理论上可以到达的遍历位置
A.(x+2, y-1)
B. (x-2, y+1)
C. (x-2, y-1)
D.(x-1, y+2)
24、对于n皇后问题,需要满足( )。
A.任意两个皇后不能处在同一左斜线
B.任意两个皇后不能处在同一列
C.任意两个皇后不能处在同一右斜线
D.任意两个皇后不能处在同一行
25、在n皇后问题中,如果在棋盘的某一个位置(i,j)去除一个皇后,则()、
A.A[i][j]=0
B.M[j]=0
C.R[i-j+N]=0
D.L[i+j]=0
26、在N皇后问题中,需要将棋盘当做一个二维数组来分析,对于该二维数组,以下说法正确的是()。
A.对于任意一条左斜线上的两个点,它们的横坐标和纵坐标相加的值相同。
B.对于任意一条左斜线上的两个点,它们的横坐标和纵坐标相减的值相同。
C.对于任意一条右斜线上的两个点,它们的横坐标和纵坐标相加的值相同。
D.对于任意一条右斜线上的两个点,它们的横坐标和纵坐标相减的值相同。
三、判断题
1、程序是算法用某种程序设计语言的具体实现。在程序中,每条指令的执行次数有限,执行每条指令的时间也有限。(×)
2、使用递归对整数进行求和的速度比使用循环的速度更快。(×)
3、不管有多少个圆盘,对于有三根柱子的标准汉诺塔问题而言,最底层的最大圆盘的最少移动次数都是1次。(√)
4、使用分治法求解问题时需要将待求解的较大规模的问题分割成k个更小规模的子问题。然后对这k个子问题分别求解:如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归进行下去,直到问题规模足够小、可以直接求出其解为止;最后将求出的小规模的问题的解合并为一个更大规模的问题的解,自顶向下逐步求出原来问题的解。(×)
5、对于整数划分问题而言,正整数7有13种划分。(×)
6、在求解全排列问题时,可以使用循环重复执行“交换位置,后面再接上剩余序列的全排列”的方式来产生所有排列情况。(×)
7、在整数划分问题中,有一些子问题被重复计算多次,我们可引入一个数组来保存已经计算过的子问题的解,在递归求解子问题之前先判断是否计算过。如果计算过就直接返回已求得的解,如果没有计算过则递归进行计算。(√)
8、二分查找又称为折半查找,它是一种高效的查找方法,但是二分查找要求待查找列表中的元素是有序的。在二分查找中,每执行一次循环或递归,待搜索列表的大小将减少一半。在最坏情况下,二分查找的比较次数为logn+1次。(√)
9、快速排序是对冒泡排序的一种改进,它通过分区函数将待排序数据分为两组,其中一组中的数据都比(√)
10、快速排序是对冒泡排序的一种改进,它通过分区函数将待排序数据分为两组,其中一组中的数据都比另一组中的数据大,再递归对两组中的数据分别进行快速排序。(√)
11、在棋盘覆盖问题中,可以将2^kx2k大棋盘分割为四个2^(k-1)×2^(k-1)的小棋盘,在分割的同时实现一次L型骨牌的覆盖,再递归覆盖四个小棋盘。(√)
12、归并排序将两个或两个以上的有序子序列合并成为一个更长的有序序列,它是分治法的典型应用之一。通常采用的是二路归并排序,即将两个任意的有序子序列归并为一个有序序列。(×)
13、动态规划的基本步骤是先找出最优解的性质,并刻画其结构特征,然后递归地定义最优值,以自底向上的方式计算出最优值,最后根据计算最优值时得到的信息,构造最优解。(√)
14、使用分治算法可对大整数乘法运算进行改进,通过减少乘法次数,将4次乘法操作改为3次乘法操作,可将时间复杂度由O(n^2)降低到O(n^1.59)。(√)
15、在计算最长公共子序列的长度时,为了减少空间需求可以使用滚动数组。给定两个序列,长度分别为m和n,可以将短的序列作为行,长的序列作为列,最后可将空间需求减至O(min(m,n))。(√)
16、在使用动态规划算法求解矩阵连乘问题时需要编写三重循环,最外层循环用于逐个计算每一条斜线上的值,中间层循环用于逐条计算斜线,最内层循环用于寻找最优值。最内层循环体内的计算量为O(1),而3重循环的总次数为O(n^3),因此,算法的时间复杂度为T(n)= (n^3)。
17、对于一套面值已经确定的硬币,如果采用贪心算法来求解找硬币问题,一定可以得到最优解;而如果使用动态规划算法,则不一定能够得到最优解。(×)
18、对于部分背包问题,所采用的贪心策略是优先选择单位价值重量大的物品。(×)
19、在并查集中,如果需要判断两个元素是否属于同一个集合,只需要判断它们所在集合的根结点是否相同即可。(√)
20、采用贪心算法求解最优装载问题的主要计算量在于对集装箱进行排序。(√)
21、在Kruskal算法中,首先需要将图中的边按权重从小到大排序;然后逐个进行判断,如果当前的边加入以后不会产生环,那么就把当前边作为最小生成树的一条边;一共选取(V-1)条边(V为顶点数),最终得到的结果就是最小生成树。(√)
22、回溯法的基本思想是从问题的某一种初始状态出发,搜索从这种状态出发所能达到的所有状态,当一条路走到“尽头”的时候(即不能再前进时),后退一步或若干步;再从另一种可能的状态出发,继续搜索,直到所有的“路径”(状态)都试探过为止。(√)
23、回溯法将问题的解空间转化成图或者树的结构表示,然后以广度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索(×)
24、在油田问题中,每次在访问一个表示油田的格子时,先检查它是否有记录已访问过的编号,从而避免同一个格子访问多次;每成功访问一个表示油田的格子时给它标记一个编号。(√)
25、马的遍历问题是否有可行解,与棋盘大小和马的初始位置无关。 (×)
26、给定无向连通图G和m种不同颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色方案使G中每条边的两个顶点着不同颜色,则称这个图是m可着色的。
(√)