(PTA)数据结构(作业)1、基本概念

判断题

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,则在不改变数组的前提下,查找最大元素的时间复杂度是:

AO(N^2)
BO(NlogN)
CO(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++;
AO(1)
BO(N)
CO(N^{2})
DO(log_{2}N)

循环次数是常量,所以是常量级的时间复杂度。

4、下面代码段的时间复杂度是()。

for ( i=0; i<n; i++ )
    for ( j=0; j<m; j++ )
        a[i][j]=0;
AO(1)
BO(mn)
CO(m^{2})
DO(n^{2})

循环次数由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;
AO(1)
BO(log2​n)
CO(n)
DO(n^{2})

两层循环都是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];
AO(m × n × t)
BO(m + n + t)
CO(m + n × t)
DO(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)
AO(1)
BO(n)
CO(i)
DO(i × n)

i 和 n 都是常数。

14、算法分析的目的是( )。

A找出数据结构的合理性
B研究算法中的输入和输出的关系
C分析算法的效率以求改进
D

分析算法的可读性和简明性

算法分析即是主要从时间复杂度和空间复杂度分析算法,而从这两方面分析只能是为了优化算法加快运算速度,提升效率。(我的想法)

15、算法的时间复杂度与( )有关。

A问题规模
B计算机硬件的运行速度
C源程序的长度
D编译后执行程序的质量

最主要跟问题规模有关,不考虑计算机的软硬件等环境因素的话。

16、某算法的时间复杂度是O(n^2),表明该算法的( )。

A问题规模是n^{2}
B问题规模与n^{2}成正比
C执行时间等于n^{2}
D执行时间与n^{2}成正比

一般情况下,算法中基本语句重复执行的次数是问题规模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;
}
AO(N^{3})
BO(N^{4})
CO(N^{5})
DO(N^6)

上边是N^4,下边是N^2,取大的那个就好。

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++;
AO(N^2)
BO(N^{3})
CO(N^2 * logN)
DO(N^3 * logN)

 外层n,内层n^2,问题规模即是n^3

19、下列代码的时间复杂度是:

for(i=0; i<n; i++)
  for(j=i; j>0; j/=2)
     printf(“%d\n”, j);
AO(N×i)
BO(N)
CO(N^2)
DO(NlogN)

外层循环到n,内层循环次数是 2^n = j,j的变化是从0到n(一个极大的数)即循环次数n = log_{2}N

两者相乘即为 D (笑,不太会讲,大概这样)

20、要判断一个整数N(>10)是否素数,我们需要检查3到\sqrt{N}之间是否存在奇数可以整除N。则这个算法的时间复杂度是:

AO(N/2)
BO(\sqrt{N})
CO(\sqrt{N}logN)
DO(0.5logN)

循环从3逐个到\sqrt{N},所以时间复杂度是O(\sqrt{N})

编程题

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数组并没有重新开始遍历,所以并不是常见的双循环的n^2,而是 i + j,即时间复杂度时O(n).

其实n^2暴力解法也能解,但是时间测试不通过,会超时。

这道题目是求一个表达式的结果,表达式中包含了欧拉函数和向下取整操作。需要注意的是,最后结果需要对一个给定的mod取模。 首先,我们可以把这个表达式分成两部分来计算。第一部分是计算φ(i)的前缀和,第二部分是计算⌊n/i⌋的前缀和。 对于第一部分,我们可以使用线性筛法来计算φ(i)的前缀和。具体步骤如下: 1. 初始化一个数组phi,大小为k+1,用来保存欧拉函数的值。 2. 初始化一个数组prime,用来保存质数。 3. 初始化一个数组isPrime,大小为k+1,用来标记是否是质数。 4. 初始化一个数组sumPhi,大小为k+1,用来保存φ(i)的前缀和。 5. 遍历2到k的每个数i,如果isPrime[i]为true,则将i加入到prime数组中,并且令phi[i] = i-1。 否则,找到i的最小质因数p,令phi[i] = phi[i/p] * p / (p-1)。 6. 遍历prime数组中的每个质数p,更新phi数组中所有p的倍数的值,令phi[i] = phi[i] * p / (p-1)。 7. 计算sumPhi数组的前缀和,即sumPhi[i] = sumPhi[i-1] + phi[i]。 对于第二部分,我们可以使用容斥原理来计算⌊n/i⌋的前缀和。具体步骤如下: 1. 初始化一个数组sumDiv,大小为k+1,用来保存⌊n/i⌋的前缀和。 2. 遍历1到k的每个数i,计算sumDiv[i] = sumDiv[i-1] + ⌊n/i⌋。 3. 使用容斥原理,减去所有的sumDiv[i] * φ(i),其中i为k的因子。 最后,将第一部分和第二部分的结果相乘,并对mod取模,即可得到最终结果。 以上就是求解这道题目的思路和步骤。希望对你有帮助!如果有任何疑问,请随时提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值