判断题
1、算法分析的两个主要方面是时间复杂度和空间复杂度的分析。 T
2、在任何情况下,时间复杂度为O(n^2) 的算法比时间复杂度为O(n*logn)的算法所花费的时间都长。 F
O(n^2)
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
}
}
O(n*logn)
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j*=a)//a小于2 当log的底小于2时,O(n^2)的算法比O(n*logn)的时间短。
{
}
}
3、O(n^2),O(1+2+···+n) 对应的算法时间复杂度相同。 T
后者时间复杂度为n(n+1)/2,最高阶一样。
4、对于某些算法,随着问题规模的扩大,所花的时间不一定单调增加。 T
O(1)常量复杂度的算法所花的时间与问题规模无关。
5、算法可以没有输入,但是必须有输出。 T
算法必须满足5个重要特性:有穷性,确定性,可行性,输入,输出。
一个算法可以有0个或多个输入,而要有一个或多个输出。
6、数据项是数据的最小单位。 T
7、数据元素是数据的最小单位。 F、
数据元素是数据的基本单位。
8、数据结构概念包括数据之间的逻辑结构、数据在计算机中的存储方式和数据的运算三个方面。 T
即逻辑结构,存储结构,算法
9、数据元素可以由类型互不相同的数据项构成。 T
数据元素是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。在有些情况下,数据元素也称为元素、记录等。数据元素用于完整地描述一个对象。
如这一行数据即为一个数据元素。
学号 | 姓名 | 性别 | 籍贯 | 专业 |
060214201 | 杨阳 | 男 | 安徽 | 计算机科学与技术 |
10、算法的优劣与算法描述语言无关,但与所用计算机有关。 F
算法的优劣是与算法自身的时间复杂度和空间复杂度相关的,与语言无关,也与计算机无关。
课本内容:评价算法优劣的基本标准:正确性,可读性,健壮性,高效性。
高效性即时间和空间两个方面。
选择题
1、给定N×N的二维数组A,则在不改变数组的前提下,查找最大元素的时间复杂度是:
A | O(N^2) |
B | O(NlogN) |
C | O(N) |
D | (N2logN) |
//我写的例子,没细看,应该不会有问题,的吧?
int A[3][3] = { { 2,4,5 }, { 1,3,6 },{3,8,9} };
int max = A[0][0];
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
}
2、以下数据结构中,( )是非线性数据结构。
A | 树 |
B | 字符串 |
C | 队列 |
D | 栈 |
线性结构:数据元素之间存在一对一的关系。字符串,队列,栈都是线性结构。
非线性结构:不是一对一的关系。(笑)树是一对多的关系。
3、下面程序段的时间复杂度是()。
x=90;
y=100;
while(y>0)
if(x>100)
{ x=x-10; y--; }
else x++;
A | O(1) |
B | O(N) |
C | O() |
D | O() |
循环次数是常量,所以是常量级的时间复杂度。
4、下面代码段的时间复杂度是()。
for ( i=0; i<n; i++ )
for ( j=0; j<m; j++ )
a[i][j]=0;
A | O(1) |
B | O(mn) |
C | O() |
D | O() |
循环次数由m和n决定,两者之间是乘积关系,所以时间复杂度是O(mn)。
5、下面代码段的时间复杂度是()。
s=0;
for ( i=0; i<n; i++ )
for( j=0; j<n; j++ )
s+=B[i][j];
sum=s;
A | O(1) |
B | O(log2n) |
C | O(n) |
D | O() |
两层循环都是n次,次数为n*n。简单)
6、数据的()包括集合、线性结构、树形结构和图形结构四种基本类型。
A | 存储结构 |
B | 逻辑结构 |
C | 基本运算 |
D | 算法描述 |
逻辑结构:数据的逻辑结构是从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的,因此,数据的逻辑结构可以看作从具体问题中抽象出来的数学模型。
数据的逻辑结构有两个要素:一是数据元素;二是关系。数据元素的含义如前所述,关系是指数据元素的逻辑关系。根据数据元素之间的不同特性,数据的逻辑结构通常有4类基本逻辑结构,它们的复杂程度依次递进:集合结构,线性结构,树结构,图结构或网状结构。
存储结构:数据对象在计算机中的存储表示称为数据的存储结构,也称为物理结构。把数据对象存储到计算机时,通常要求既要存储各数据元素的数据,又要存储数据元素之间的逻辑关系,数据元素在计算机内用一个节点来表示。数据元素在计算机中有两种基本的存储结构,分别是顺序存储结构和链式存储结构。
(抄的书上内容。笑)
7、下面的程序段违反了算法的()原则。
void sam()
{ int n=2;
while (n%2==0) n+=2;
printf(“%d”,n);
}
A | 有穷性 |
B | 确定性 |
C | 可行性 |
D | 健壮性 |
算法必须满足5个重要特性:有穷性,确定性,可行性,输入,输出。
题中n=2进入循环每次+2,无法结束循环,所以违反了有穷性。
8、下列关于数据的逻辑结构的叙述中,()是正确的。
A | 数据的逻辑结构是数据元素间关系的描述 |
B | 数据的逻辑结构反映了数据在计算机中的存储方式 |
C | 数据的逻辑结构分为顺序结构和链式结构 |
D | 数据的逻辑结构分为静态结构和动态结构 |
逻辑结构:数据的逻辑结构是从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的,因此,数据的逻辑结构可以看作从具体问题中抽象出来的数学模型。数据的逻辑结构有两个要素:一是数据元素;二是关系。
(所以就是数据元素和它们之间的关系嘛)
9、在数据结构中,从逻辑上可以把数据结构分成()。
A | 动态结构和静态结构 |
B | 紧凑结构和非紧凑结构 |
C | 线性结构和非线性结构 |
D | 内部结构和外部结构 |
数据结构有四种基本结构,即集合结构,线性结构,树结构,图结构或网状结构。线性结构自成一类,另外三种为非线性结构。
10、计算机算法必须具备输入、输出和()等五个特性。
A | 可行性、可移植性和可扩充性 |
B | 可行性、确定性和有穷性 |
C | 确定性、有穷性和稳定性 |
D | 易读性、稳定性和安全性 |
算法必须满足5个重要特性:有穷性,确定性,可行性,输入,输出。
11、在数据结构中,与所使用的计算机无关的数据结构是()。
A | 逻辑结构 |
B | 存储结构 |
C | 逻辑结构和存储结构 |
D | 物理结构 |
逻辑结构:数据的逻辑结构是从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的,因此,数据的逻辑结构可以看作从具体问题中抽象出来的数学模型。
12、下面程序的时间复杂度为()。
for(i = 0; i < m; i++)
for(j = 0; j < t; j++)
c[i][j] = 0;
for(i = 0; i < m; i++)
for(j = 0; j < t; j++)
for(k = 0; k < n; k++)
c[i][j] = c[i][j]+a[i][k] * b[k][j];
A | O(m × n × t) |
B | O(m + n + t) |
C | O(m + n × t) |
D | O(m × t + n) |
上边 m*t ,下边 m*n*t。取大的。
13、下列程序段的时间复杂度为()。
i = 1; k = 0; n = 100;
do{
k = k + 10 * i;
i = i++;
}while(i != n)
A | O(1) |
B | O(n) |
C | O(i) |
D | O(i × n) |
i 和 n 都是常数。
14、算法分析的目的是( )。
A | 找出数据结构的合理性 |
B | 研究算法中的输入和输出的关系 |
C | 分析算法的效率以求改进 |
D | 分析算法的可读性和简明性 |
算法分析即是主要从时间复杂度和空间复杂度分析算法,而从这两方面分析只能是为了优化算法加快运算速度,提升效率。(我的想法)
15、算法的时间复杂度与( )有关。
A | 问题规模 |
B | 计算机硬件的运行速度 |
C | 源程序的长度 |
D | 编译后执行程序的质量 |
最主要跟问题规模有关,不考虑计算机的软硬件等环境因素的话。
16、某算法的时间复杂度是O(),表明该算法的( )。
A | 问题规模是 |
B | 问题规模与成正比 |
C | 执行时间等于 |
D | 执行时间与成正比 |
一般情况下,算法中基本语句重复执行的次数是问题规模n的某个函数f(n),算法的时间量度基座:
T(n)=O(F(n))
它表示随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。
17、下列代码的时间复杂度是:
if ( A > B ) {
for ( i=0; i<N*N/100; i++ )
for ( j=N*N; j>i; j-- )
A += B;
}
else {
for ( i=0; i<N*2; i++ )
for ( j=N*3; j>i; j-- )
A += B;
}
A | O() |
B | O() |
C | O() |
D | O() |
上边是,下边是,取大的那个就好。
18、Choose the time complexity of the following code:
x=0;
for(i=0;i<n;i++)
for(j=0;j<i*i;j++)
x++;
A | O() |
B | O() |
C | O() |
D | O() |
外层n,内层,问题规模即是
19、下列代码的时间复杂度是:
for(i=0; i<n; i++)
for(j=i; j>0; j/=2)
printf(“%d\n”, j);
A | O(N×i) |
B | O(N) |
C | O() |
D | O(NlogN) |
外层循环到n,内层循环次数是 ,j的变化是从0到n(一个极大的数)即循环次数n =
两者相乘即为 D (笑,不太会讲,大概这样)
20、要判断一个整数N(>10)是否素数,我们需要检查3到之间是否存在奇数可以整除N。则这个算法的时间复杂度是:
A | O(N/2) |
B | O() |
C | O(logN) |
D | O(0.5logN) |
循环从3逐个到,所以时间复杂度是O()
编程题
7-1 买买买 (12 分)
刚过完双十一,马上又来双十二, LC 向来人*钱多,他现在有 A 元钱,他想买 B 元一瓶的快乐水。老板还给了他九折的优惠,请问 LC 最多能买多少瓶快乐水
输入格式:
在一行中给出2个两个正整数 A,B(1<=A<=10^6,1<=B<=10)。
输出格式:
在一行中输出 LC 最多能买的快乐水的数量。
输入样例:
90 10
输出样例:
10
#include<iostream>
using namespace std;
int main()
{
int A, B;
cin >> A >> B;
cout << (int)(A / (B * 0.9)) << endl;
//int 与 float 运算 隐式转换成了 float 类型的数据,所以重新转回 int 类型。
}
7-2 点钞 (12 分)
Bear_2 有一个小金库,里面有 n 张钞票。现在他想按顺序点钞,如果点到的这张钞票之前有过同等金额,就输出 ∗ ,否则输出这张钞票的金额。
保证,钞票的金额不超过 10^3 。
输入格式:
第一行中给出1个正整数 n(1<=n<=10^3) 代表金库里有 n 张钞票。
第二行给出 n 个正整数,第 i 个整数 Xi 代表第 i 张钞票的金额。
输出格式:
在一行内,对每张钞票输出对应的金额,如果之前没有过同样金额的钞票;否则输出 ∗
注意,两个输出中间用空格隔开,行末不要有空格
输入样例:
5
1 2 1 3 2
输出样例:
1 2 * 3 *
#include<iostream>
using namespace std;
int main()
{
int number,i;
int money ;
int a[1001] = {0};
//题中说明了金额上限,所以直接可以声明数组的大小,以下标存值
//0,1分别代表没有当前面值的钞票和有当前面值的钞票。
cin >> number;//输入数量
for (i = 0; i < number; i++)
{
cin >> money;//输入面值
if (a[money])//初始为0,所以不输出 *
{
cout << "*";
}
else
{
cout << money;
}
if (i != number - 1)
{
cout << " " ;
}
a[money] = 1;//记录当前面值已存在
}
}
7-3 无情的点钞机 (12 分)
总所周知 LC 是集训队买单最快的人,现在 LC 有 n 张面额从 1 到 10 的钞票,他想请你帮他算算 1 到 10 金额的钞票分别有多少张。
输入格式:
第一行中给出1个正整数 n(1<=n<=10^3) 代表金库里有 n 张钞票。
第二行给出 n 个正整数,第 i 个整数 Xi 代表第 i 张钞票的金额。
输出格式:
在一行内输出 10 个整数,第 i 个整数代表金额为 i 的钞票的数量,两个数之间用一个空格隔开,注意行末不要有空格
输入样例:
5
1 2 1 3 2
输出样例:
2 2 1 0 0 0 0 0 0 0
#include <iostream>
using namespace std;
int main()
{
int number, i;
int money;
int a[1001] = { 0 };//基本等同上一题
cin >> number;
for (i = 0; i < number; i++)
{
cin >> money;
if (a[money])//面值已存在的话记录+1
{
a[money] ++;
}
else//面值先前不存在的话更改状态为存在
{
a[money] = 1;
}
}
for (i = 1; i < 11; i++)
{
cout << a[i] ;
if (i != 10)
{
cout << " ";
}
}
}
7-4 数组元素的目标和 (14 分)
知识点:双指针
给定两个升序排序的有序数组 A 和 B,以及一个目标值 x。
数组下标从 0 开始。
请你求出满足 A[i]+B[j]=x 的数对 (i,j)。
数组长度不超过 10^5。 同一数组内元素各不相同。 1≤数组元素≤10^9
输入格式:
第一行包含三个整数 n,m,x,分别表示 A 的长度,B 的长度以及目标值 x。
第二行包含 n 个整数,表示数组 A。
第三行包含 m 个整数,表示数组 B。
输出格式:
共一行,包含两个整数 i 和 j。
输入样例:
4 5 6
1 2 4 7
3 4 6 8 9
输出样例:
1 1
#include <iostream>
using namespace std;
int main()
{
int n, m, x;
cin >> n >> m >> x;
int *A = new int[n];
int *B = new int[m];
for (int i = 0; i < n; i++)
{
cin >> A[i];
}
for (int i = 0; i < m; i++)
{
cin >> B[i];
}
for(int i = 0, j = m - 1; i < n; i ++ )
{
while(j >= 0 && A[i] + B[j] > x) j -- ;
if(j >= 0 && A[i] + B[j] == x) cout << i << " " << j <<endl;
}
}
两个升序排列的数组
A数组从最小开始遍历,B数组从最大开始遍历
因为是升序排列,所以两者之和与目标值的比较关系是按照,大于,等于,小于,来变化的
当两者之和大于目标值的时候,B数组指针向左移动,然后进行判断
当B数组由于移动一位后,变化的数字差值过大,导致两者之和小于目标值,那么A数组的数字向右移动一位。
当两者之和等于目标值时,输出 i 和 j 的值。
在此种方法下,A数组最多遍历到 i ,B数组最多遍历 j ,在A数组的取值右移的时候,B数组并没有重新开始遍历,所以并不是常见的双循环的,而是 i + j,即时间复杂度时O(n).
其实暴力解法也能解,但是时间测试不通过,会超时。