赞
踩
1:本人真的是一个算法菜鸡,但是个人认为这门课听了也对算法没什么提升,自学占大头。(希望真的能够2024年之前学会算法和数据结构,以及24年dp杯能榜上有名吧...)
2:后续可能会更新一个期末复习整理的大纲,由于csdn改版之后图片复制老是加载不了,所以如果要发出来的话挺耗时间的,之后没发就当我没说过这个事情(嗯)。
电子文件大纲(完整梳理版)更新:【算法设计与分析】期末汇总资源-CSDN文库
手写大纲更新:
1:
【问题描述】给定一个按值有序(升序)的N元整数数组A,采用折半查找法查找关键值k的位置,并给出查找的过程
【输入形式】
第一行:N
第二行:A[0], A[1], ... , A[N-1]
第三行:k
【输出形式】
第一行:k的位置(索引),若不存在则输出‘no’
第二行:查找的过程,每一次折半的中间(mid)位置的值,以逗号分隔。例如,1 2 3 4 5的中间位置为3,1 2 3 4的中间位置为2。
【样例输入】
样例1
11
2,5,8,11,15,16,22,24,27,35,50
22
样例2
11
2,5,8,11,15,16,22,24,27,35,50
10
【样例输出】
样例1
6
16,27,22
样例2
no
16,8,11
【样例说明】
【评分标准】必须使用折半法,其他方法不能得分。
- #include <stdio.h>
- #include <stdlib.h>
-
- int main(){
- //input
- int N;
- scanf("%d",&N);
- int *A=(int*)malloc(sizeof(int)*N);
- int i=0;
- for(i=0;i<N;i++){
- //cin>>A[i];
- scanf("%d",&A[i]);
- }
- int k;
- //cin>>k;
- scanf("%d",&k);
-
- //half search
- int left=0,right=N-1,mid;
- int cnt=0;
- int flag=0;
- while(left<=right){
- mid=(left+right)/2;
-
- if(k<A[mid]){
- right=mid;
- }
- else if(k>A[mid]){
- left=1+mid;
- }
- else{//k==mid
- flag=1;
- break;//found
- }
-
- if(cnt==0) //cout<<A[mid];
- {
- printf("%d",A[mid]);
- }
- else{
- printf(",%d",A[mid]);
- }
- //else cout<<","<<A[mid];
- cnt++;
- }
-
- if(flag=1){
- //cout<<mid;//output the number
- printf("%d",mid);
- }
- else{
- printf("no");
- }
- return 0;
- }
- //2 5 8 11 15 16 22 24 27 35 50
2:
【问题描述】一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少种跳法,并分析算法的时间复杂度,例如
n 为1 时只有一种跳法
n 为2 时只有两种跳法
【输入形式】输入一个整数n
【输出形式】n级的跳法数,整数m
【样例输入】
6
【样例输出】
13
【样例说明】
输入与输出均为整数
【答题要求】
要求在注释中首先解释求解思路,如果有递推关系,必须说明为什么是这样的关系,递推计算是通过什么道理建立起来的,否则不得分。
需要指出使用了所学过的什么方法,并明确写出算法的时间复杂度。仅使用蛮力法的求解将严重失分。
- #include <stdio.h>
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
- #define MAX 10000000
-
-
- /*
- 用front、mid、rear存放暂态
- 类似用三个变量实现dp,使用过程中不断变表
-
- 参考斐波那契数
- 跳上n阶梯子需要前面梯子做基础
- 若差一阶和f(n-1)相同
- 若差两阶f(n-2)相同
- 时间复杂度为O(N)
- */
- int fun(int n){
- if(n<2){
- return 1;
- }
- int front=1,mid=1,rear=1;
- for(int i=2;i<=n;i++){
- front=mid;
- mid=rear;
- rear=(front+mid)%MAX;
- //max为取余,防止数字过大
- }
- return rear;
- }
-
- int main(){
- //input
- int n;
- cin>>n;
-
- cout<<fun(n);
- return 0;
- }
3:
【问题描述】
输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
【输入形式】
一个升序排序的数组以空格隔开,以及一个目标数字,换行输入
【输出形式】
如果存在数组中两个数字和为目标数字,则输出数字对;
如果存在多个满足条件的数字对,输出一对即可;
不存在则不输出;
【样例输入】
1 2 4 7 11 15
15
【样例输出】
4 11
【样例说明】
4+11=15
【评分标准】
时间复杂度必须为 O(n),否则酌情给分。
注释中要首先说明求解思路。
- #include <stdio.h>
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
-
- int main(){
- //输入
- int n;//元素个数
- cin>>n;
- int *a=(int*)malloc(sizeof(int)*n);
- for(int i=0;i<n;i++){
- cin>>a[i];
- }
- int target;
- cin>>target;
-
- //查找对应的元素 ,cnt可以用于估算时间复杂度
- int flag=0,front=0,rear=n-1,cnt=0;
- //双指针,front指向从头开始的元素,rear指向从尾开始的元素
- while(front<rear){
- //序列非负的情况下,如果target始终大于起始值,则两数一定在前面
- //但是好像没说非负
- /*
- if(a[rear]>target){
- rear--;
- cnt++;
- continue;
- }*/
-
- //找到两数
- if(a[front]+a[rear]==target){
- flag=1;
- cnt++;
- break;
- }
-
- //如果和偏大,则说明rear取大了
- else if(a[front]+a[rear]>target){
- rear--;
- cnt++;
- }
-
- //如果和偏小,则说明front取小了
- else{
- front++;
- cnt++;
- }
- }
-
- if(flag==1){
- cout<<a[front]<<" "<<a[rear];
- }
- //cout<<cnt;
- return 0;
- }
- /*
- 6
- 1 2 4 7 11 15
- 15
4:
【问题描述】在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如
在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。
【输入形式】整数数组,空格隔开
【输出形式】数对之差的最大值,一个数字
【样例输入】
2 5 8 19 3 6
【样例输出】
16
【样例说明】题目要求输出数对之差的最大值,即数字减去右边数字的值,不一定为数组中最大值和最小值的差。
【评分标准】要求设计时间和空间复杂度最低、代码最简洁的方法。性能越好得分越高。
如使用蛮力法求解得分最低。注释中要明确解释求解思路与所采用的方法。
- #include <stdio.h>
- #include <stdlib.h>
- #include <iostream>
- using namespace std;
-
- int main(){
- //input
- int n;
- cin>>n;
- int *a=(int*)malloc(sizeof(int)*n);
- for(int i=0;i<n;i++){
- cin>>a[i];
- }
-
- //特殊情况讨论
- if(n==0){
- return 0;
- }
- if(n==2){
- cout<<a[1]-a[0];
- return 0;
- }
-
- //动态规划,maxD记录差值最大值,max记录从右侧开始的最大值
- int maxD=0,max=a[n-1];
- for(int i=n-2;i>=0;i--){
- //前面一个数大于当前max
- if(a[i]>max){
- max=a[i];//更新max
- }
- //当前值小于max,判断差值大小
- else{
- //如果max减去当前值比maxD大
- if(max-a[i]>maxD){
- maxD=max-a[i];//更新maxD
- }
- }
- }
- //时间复杂度为O(n),空间复杂度O(1)
-
- cout<<maxD<<endl;
- return 0;
- }
【一】
1:tsp的英文全称。
2:各类概率算法的全称。
3:根据T(n-1)计算大O。
4:回溯法的TSP问题的解空间树。
5:L型骨牌的数目计算公式。
6:给出概率pi和时间ti,分析算法的时间复杂度。
7:大O、大Ω、大Θ的含义。
【三】
3.1:给出f(n)和g(n)的公式,包括绝对值、log对数、取整等,求阶相关的大O、大Ω、大Θ,并给出其中对应符号最大和最小的函数。
3.2:KMP的主要思想。
3.3:汉诺塔的伪代码。
3.4:根据问题规模和算法时间T(n),求解计算机在速度性能上翻倍之后且算法不变的情况下,能解决的问题规模为多少?
【四】
4.1:根据T(n-1)计算大Θ。
4.2:快排的伪代码,分析时间复杂度。
4.3:用贪心法算开车加油的最少次数(有n个加油站,初始的时候没油,给出了各加油站距离起始点的位置,油箱容量为m),给出具体的贪心策略,并分析时间复杂度。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。