文章目录

  • 各周链接
  • 题目
    • 第一周
      • 上课题目
        • 素数判断
          • 思路
          • 代码
            • 解法1.暴力
            • 解法2.优化部分
        • 唯一重复值查找
          • 思路
          • 代码
            • 解法1.暴力 暴力比对
            • 解法2.利用数组查重
      • 作业题目
        • [LeetCode]11. 盛最多水的容器
          • 题目思路:
          • 题目代码:
            • 解法1:双指针,动态规划
            • 解法2:蛮力算法
      • 自学题目
        • 异或解决唯一重复值查找问题
          • 思路
          • 代码
            • 解法1.暴力比对
    • 第二周
      • 上课题目
        • 试题A: 组队
          • 数据
          • 思路
          • 代码
            • 解法1.枚举
            • 解法2.贪心
            • 解法3.深度优先搜索
            • 解法4.动态规划
        • 试题C: 数列求值
          • 思路
          • 代码
      • 作业题目
        • 注意----所有人做这2个题目的时候,使用2种方法,其中一种必须用枚举书写!
        • 试题F: 特别数的和
          • 思路
          • 代码
            • 解法1.枚举
          • 解法2.递归
        • 等差数列
          • 思路
          • 代码
            • 解法1. GCD 欧几里得算法
            • 解法2. 枚举
      • 自学题目
    • 第三周
      • 上课题目
        • 例1 输入n的值,求n!
          • 思路
          • 代码
            • 解法1.递推
            • 解法2.递归
        • 例2 输入n的值,求得并输出第n个fibonacci数列的数值。
          • 思路
          • 代码
            • 解法1.递推
            • 二叉树递归
        • 例3 选择法排序
          • 思路
          • 测试数据
          • 代码
        • 例4 冒泡法排序:
          • 思路
          • 测试数据
          • 代码
      • 作业题目
        • 1137. 第 N 个泰波那契数
          • 提示:
          • AC截图
          • AC代码
            • 解法1.递推
            • 解法2.记忆化搜索
        • 面试题10- II. 青蛙跳台阶问题
          • 思路
          • AC截图
          • AC代码
            • 解法1.记忆化递推
        • 面试题 16.11. 跳水板
          • 思路
            • AC截图
            • AC代码
            • 解法1.枚举
            • 解法2.递归
      • 自学题目
          • P62页,例2.12 拆分输出
          • 思路
          • 代码
            • 解法1.递归
        • P66页 n皇后的问题
          • 思路
          • 代码
            • 解法1.DFS 深度优先搜索
          • 了解更多
        • hanoi 汉诺塔问题
          • 思路
          • 代码
            • 解法1.递归
          • 了解更多
    • 第四周
      • 上课题目
        • 题目计分
          • 思路
          • 代码
            • 解法1.二进制枚举写法
            • 解法2.dfs版本
          • 答案
        • 打印图形 我觉得不考 待补
          • 思路
          • 代码
          • 了解更多
      • 下课题目
          • 看图写码 我觉得不考 待补
          • 思路
          • 代码
        • 图选数字
          • 数据
          • 答案
          • 代码
            • 解法1. DFS深度优先搜索
          • 吐槽
          • 了解更多
      • 自学题目
    • 第五周
      • 上课题目
        • 快速排序
          • 思路
          • 代码
          • 测试数据
          • 了解更多
      • 下课题目
      • 自学题目
    • 第六周
      • 上课题目
        • 归并排序
          • 思路
          • 代码
          • 了解更多
        • 例2 折半查找
          • 思路
          • 代码
          • 测试数据
        • 例3 最重要的程序 我觉得不考 待补
      • 作业题目
        • 硬币称重
          • 思路
          • 代码
            • 解法1.二分递归+位运算
      • 自学题目
          • 折半思考题
          • 代码
            • 解法1.二分递归
          • 测试数据
          • 注意
        • P91页 查找最大值和次大值
          • 思路
          • 代码
            • 解法1.二分递归
          • 了解更多
        • P96 寻找2个等长有序序列的中位数
          • 思路
          • 代码
    • 第七周
      • 上课题目
        • 插入排序
          • 思路
          • 代码
          • 测试数据
          • 了解更多
        • 例2 1,2,3,4可以组成那些没有重复的4位数值
          • 思路
          • 代码
            • 全排列
          • 测试数据
          • 输出数据
        • 例3 0/1背包问题
          • 思路
          • 代码
            • 方法一:字符串蛮力
            • 方法二:二进制枚举
            • 方法三:DFS
            • 方法三.2闫老板思考角度
            • 方法四:全排列
            • 方法五:数组蛮力
          • 答案
          • 了解更多
      • 下课题目
        • 01背包问题 枚举法【蛮力法】
          • 思路
          • 代码
            • 方法一:字符串蛮力
      • 自学题目
    • 第八周
      • 上课题目
        • 例1 0/1背包问题
          • 思路
          • 代码
            • 解法1.DFS深度优先搜索
          • 了解更多
        • 例1 求迷宫问题
          • 思路
          • 代码
            • 解法1.DFS深度优先搜索
          • 答案
          • 测试数据
          • 注意:
        • 例2 迷宫 我认为不考 待补
          • 思路
          • 代码
          • 注明
      • 下课题目
      • 自学题目
    • 第九周
      • 上课题目
        • 数列重组
          • 思路
          • 代码
            • 解法1.DFS深度优先搜索
          • 测试数据
          • 答案
      • 下课题目
      • 自学题目
    • 第十周 我认为不考 待补
      • 上课题目
      • 下课题目
      • 自学题目
    • 第十一周
      • 上课题目
        • 例1 兑换货币
          • 思路
          • 代码
            • 解法1.贪心
          • 测试数据
        • 思路
        • AC截图
        • 代码
          • 解法1.模拟
        • 单调递增的数字【选自LeetCode】
          • 思路
          • AC截图
          • AC代码
            • 解法1.暴力
            • 解法2. 贪心
      • 下课题目
      • 自学题目
        • 组队 贪心版本
          • 注释
          • 思路
          • 代码
            • 解法1.贪心版本
          • 答案
          • 提示:
        • 1029. 两地调度【来自LeetCode里面】
          • 思路
          • AC截图
          • AC代码
            • 解法1.贪心
          • 注明:
    • 第十二周
      • 上课题目
        • 例1字典序最小问题
          • 颜老板思路
          • 思路
          • 代码
          • 解法1.安全版
          • 解法2.非安全,极简版
        • 例2背包问题:
          • 思路
          • 代码
            • 解法1.结构体排序
      • 下课题目
      • 自学题目
        • 字符串去重
          • 思路
          • 代码
            • 解法1.哈希表
            • 解法1.2哈希表 写法二
            • 解法2.ASCII码
            • 解法3.set
        • 自定情况:多个字符串的情况下
          • 思路
          • 代码
            • set
            • 哈希表
            • ASCII
        • 霍夫曼编码 我认为不考 待补
        • 第三届蓝桥杯【省赛试题8】密码发生器
          • 思路
          • 代码
            • 解法1.语法糖 哈夫曼距离应用

各周链接

第一周全解
第二周全解
第三周全解
第四周全解
第五周全解
第六周全解
第七周全解
第八周全解
第九周全解
第十周只有一道题,日期安排题目,我感觉八成不考,也想不到更好的做法
第十一周全解
第十二周全解

题目

第一周

上课题目

素数判断

如果假设判断的数是x

所谓素数就是质数:只能被1和其本身整除的数其实任何一个正整数都能被1和其本身整除(1和x没必要判断)只需要去判断除开1和x以外的其他数(也就是2到x-1范围中的数)与x本身之间的整除关系举例x=7   判断范围是 2 3 4 5 6 2到6与7都不能被整除,所以7是素数x=8   判断范围是 2 3 4 5 6 7   2与8之间是整除关系,下结论8不是素数并且3到8是没必要再进行整除判断循环提前结束了区别是素数和不是素数?
如果是素数,循环一定全部做完。
如果不是素数,循环一定提前结束。
思路
代码
解法1.暴力

#include<iostream>using namespace std;bool isPrime(int n){for(int i=2;i<n;i++)if(n%i==0)return false;return true;}int main()
{int n;cin>>n;if(isPrime(n))cout<<1;else cout<<-1;return 0;
}
解法2.优化部分
#include<iostream>
#include<cmath>using namespace std;bool isPrime(int n){for(int i=2;i<=sqrt(n);i++)if(n%i==0)return false;return true;}int main()
{int n;cin>>n;if(isPrime(n))cout<<1;else cout<<-1;return 0;
}

唯一重复值查找

1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次。设计一个算法,将它找出来,你能否设计一个算法实现?

思路
代码
解法1.暴力 暴力比对
#include<iostream>
clude<cstring>using namespace std;int main()
{int n;cin>>n;const int tmpLen = n;int a[tmpLen+10];memset(a,0,sizeof a);for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)for(int j=i+1;j<n;j++) if(a[i]==a[j])cout<<a[i];return 0;
}

数组

解法2.利用数组查重
#include<iostream>
#include<cstring>using namespace std;int main()
{int n;cin>>n;const int tmpLen = n;int a[tmpLen+10];memset(a,0,sizeof a);for(int i=0;i<n;i++){int tmpN;cin>>tmpN;a[tmpN]++;}for(int i=0;i<tmpLen+10;i++)if(a[i]>1)cout<<i;return 0;
}

作业题目

[LeetCode]11. 盛最多水的容器

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

题目思路:

有题可知我们的目标是明确能盛如多少水量,此时问题转化为水量在整个可能存在的等式当中的关系。
实际读题之后我们发现,水量受到宽度高度两个要素影响,且不是单纯递增关系,因此排出本来设想的贪心。

1.我们用最直接得想法可以瞄准暴力,列举所有可能存在再判断.
此时我们将目光瞄准为求最大水量的话,可以得到等式max_area=max(max_area,min(height[l],height[r])*(r-l))
最大水量等于所有情况中(现存宽度乘两边高度中相对较低的一边)的最大值

2.有了这个表达式之后剩下得任务则转换为降低降低频次。
依据题意两边的概念我们很容易想到双指针移动的方式,且因为等式高度关系,每次移动保持寻找更高值即可,找到尽可能最大的二位面积即可。

题目代码:
解法1:双指针,动态规划

时间复杂度:o(n)
状态 :通过

class Solution {public:int maxArea(vector<int>& height) {int max_area=0,l=0,r=height.size()-1;//max_area假设面积,l,左端点,r右端点while(l<r){max_area=max(max_area,min(height[l],height[r])*(r-l));//面积等式if(height[l]<height[r])l++;//双指针移动,尽可能保持最大面积else r--;}return max_area;}
};
解法2:蛮力算法

时间复杂度:o(n^2)
状态 :超时,48 / 50 个通过测试用例,显然能过掉大部分数据,在oi赛制还是能拿分嘛

class Solution {public:int maxArea(vector<int>& height) {int max_area=0;for(int i=0;i<=height.size()-1;i++)for(int j=i;j<=height.size()-1;j++)max_area=max(max_area,(j-i)*min(height[i],height[j]));//暴力列举所有情况判断return max_area;}
};

自学题目

异或解决唯一重复值查找问题

思路:使用C语言中的 异或     ^异或 一样为0,不一样为1如果假设x=99^0    结果是 99^9    结果是 0
思路

相同与运算就是NULL,如果是就输出

代码
解法1.暴力比对
#include<iostream>
#include<cstring>using namespace std;int main()
{int n;cin>>n;const int tmpLen = n;int a[tmpLen+10];memset(a,0,sizeof a);for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)for(int j=i+1;j<n;j++)if(int(a[i]^a[j])==NULL)cout<<a[i]<<" ";return 0;
}

第二周

上课题目

试题A: 组队

本题总分:5 分
【问题描述】
作为篮球队教练,你需要从以下名单中选出1 号位至5 号位各一名球员,
组成球队的首发阵容。
每位球员担任1 号位至5 号位时的评分如下表所示。请你计算首发阵容1
号位至5 号位的评分之和最大可能是多少?

编号1 号位2 号位3 号位4 号位5 号位

数据
1 97 90 0 0 0
2 92 85 96 0 0
3 0 0 0 0 93
4 0 0 0 80 86
5 89 83 97 0 0
6 82 86 0 0 0
7 0 0 0 87 90
8 0 97 96 0 0
9 0 0 89 0 0
10 95 99 0 0 0
11 0 0 96 97 0
12 0 0 0 93 98
13 94 91 0 0 0
14 0 83 87 0 0
15 0 0 98 97 98
16 0 0 0 93 86
17 98 83 99 98 81
18 93 87 92 96 98
19 0 0 0 89 92
20 0 99 96 95 81
思路
代码
解法1.枚举
#include<iostream>using namespace std;const int row = 20,col=5;
int fen[row+5][col+5];int main()
{for(int i=0;i<row;i++)for(int j=0;j<col;j++)cin>>fen[i][j];int res=0;for(int a=0;a<20;a++)for(int b=0;b<20;b++)for(int c=0;c<20;c++)for(int d=0;d<20;d++)for(int e=0;e<20;e++){if(a!=b&&a!=c&&a!=d&&a!=e&&b!=c&&b!=d&&b!=e&&c!=d&&c!=e&&d!=e)res=max(res,fen[a][0]+fen[b][1]+fen[c][2]+fen[d][3]+fen[e][4]);}cout<<res;return 0;
}
解法2.贪心
#include<iostream>
#include<algorithm>using namespace std;const int row = 20,col=5;
int fen[row+5][col+5];
bool st[row];//判重数组
int res;
int jIdx;//用来记录需要判重的位子,即当前选择的人是第几个人int max(int a,int b,int idx)//自定义max函数,方便判断b>a时进行操作
{if(a>b){return a;}jIdx=idx;//记录当前位子return b;
}void func()
{for(int i=0;i<col;i++)//当col过完之后,表示五个人都被选择完毕{jIdx=0;int tmp=-0x3f3f3f;for(int j=0;j<row;j++)if(!st[j])tmp = max(tmp,fen[j][i],j);//如果没选择当前这个人,更新最大值,记录这个人的位置st[jIdx]=true;//选择res+=tmp;//求和//cout<<jIdx<<" "<<i<<" "<<fen[jIdx][i]<<endl;//输出当前被选择的人员}
}int main()
{for(int i=0;i<row;i++)for(int j=0;j<col;j++)cin>>fen[i][j];func();cout<<res;//输出答案return 0;
}
解法3.深度优先搜索
#include<iostream>using namespace std;const int row = 20,col=5;
int fen[row+5][col+5];
bool st[col];void dfs(int u,int tmpS,int &sum)
{if(u==col){sum = max(sum,tmpS);return ;}else {for(int i=0;i<row;i++){if(!st[i]){st[i]=true;dfs(u+1,tmpS+fen[i][u],sum);st[i]=false;}}}}int main()
{for(int i=0;i<row;i++)for(int j=0;j<col;j++)cin>>fen[i][j];int res=0;dfs(0,0,res);cout<<res;return 0;
}
解法4.动态规划

分组背包应该可以,有空再写

试题C: 数列求值

本题总分:10 分
【问题描述】
给定数列1, 1, 1, 3, 5, 9, 17, …,从第4 项开始,每项都是前3 项的和。求
第20190324 项的最后4 位数字。

思路
代码

####### 解法1.滚动数组

#include<iostream>using namespace std;const int n = 20190324,len=1e4;
int arr[]={0,1,1,1};int main()
{for(int i=4;i<=n;i++){arr[4]=(arr[3]+arr[2]+arr[1])%len;for(int j=1;j<=3;j++)arr[j]=arr[j+1];//模拟数组滚动变化}cout<<arr[4];return 0;
}

作业题目

注意----所有人做这2个题目的时候,使用2种方法,其中一种必须用枚举书写!

试题F: 特别数的和

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分
【问题描述】
小明对数位中含有2、0、1、9 的数字很感兴趣(不包括前导0),在1 到
40 中这样的数包括1、2、9、10 至32、39 和40,共28 个,他们的和是574。
请问,在1 到n 中,所有这样的数的和是多少?

思路

暴力

代码
解法1.枚举
#include<iostream>using namespace std;int main()
{int n;cin>>n;int res=0,x=0;for(int i=1;i<=n;i++){x=i;while(x){int t=x%10;if(t==2||t==0||t==9||t==1)//一个数满足就计算一次{res+=i;break;}x/=10;}}cout<<res;return 0;
}
解法2.递归
#include<iostream>int n,res;
void check(int x,int u)
{if(!x)return ;if(x%10==2||x%10==0||x%10==9||x%10==1){res+=u;return;}check(x/10,u);
}
int main()
{while(std::cin>>n,n){int k=n;check(n--,k);}std::cout<<res;return 0;
}

等差数列

数学老师给小明出了一道等差数列求和的题目。

但是粗心的小明忘记了一部分的数列,只记得其中 N 个整数。

现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有几项?

输入格式
输入的第一行包含一个整数 N。

第二行包含 N 个整数 A1,A2,⋅⋅⋅,AN。(注意 A1∼AN 并不一定是按等差数
列中的顺序给出)

输出格式
输出一个整数表示答案。

数据范围

2≤N≤100000,
0≤Ai≤109

输入样例:

5
2 6 4 10 20

输出样例:

10

样例解释
包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、18、20。

思路

这道题真正答对需要找最大公因子,设计使用GCD欧几里得算法
按照当时的进度,大家应该是过个样例

已知给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有几项
该数列为等差数列,求等差数列最短。
我们已知等差数列求N公式为(a(n)-a(0))/d+1,即等差数列 队尾减队头的差 除以 公差 +1;
由此我们知道,本题根本不需要其余的队列数字,现在的问题转为,如何使得队伍从小到大排序
以及为(a(n)-a(0))/d+1如何才能最短。

我们可以轻松的通过sort函数排序。
而使得 (a(n)-a(0))/d+1最小则需要使得 公差最大。

由此,最后一步,我们只需要通过辗转相除法求得最大d,即可通过等差公式求得答案。

代码
解法1. GCD 欧几里得算法
#include<iostream>
#include<algorithm>using namespace std;
const int N=1e5+10;
int a[N];int gcd(int a,int b)//辗转相除法 在两个数中求得最大公约数,当一方为0时,返回另一方。
{return b?gcd(b,a%b):a;
}int main()
{int n;cin>>n;for(int i=0;i<n;i++)cin>>a[i];sort(a,a+n);//回复等差数列正常排序int d=0;for(int i=1;i<n;i++)d=gcd(d,a[i]-a[0]);//求得数列中的最大公约数,又因为辗转相除,所以gcd(a,b)中a,b任意一个为零时,可以返回另一个数,再和下一个数求最大公约数。if(d)cout<<(a[n-1]-a[0])/d+1;//特判d为0!即有常数个,否则出现K/d时d==0逻辑错误Float Point Exception   else cout<<n;return 0;
}
解法2. 枚举

数据过到如下大小出现TML,且存在4 2 5 7 10出问题的情况,但是骗分差不多够了。

100000 510735260 430427260 325696180 181874000 301759672 306932452 305279052 55941608 280950452 184132072 751002624 577721580 334194656 113777540 379200204 242109724 150227924 199239424 11427356 855625052 575553264 979653672 782662872 138044728 533084504 320962732 196466436 253485116 129664352 138531300 32973520 535413436 885268152 699714156 697300192 801516356 880152060 685844492 630937440 146949468 268181480 811805228 629737544 123986104 599182712 301155000 515785216 565835996 917249632 924118328 676542936 998393780 374343932 282995944 395190944 862531540 346344784 241046824 209518848 849805084 5361740 708467728 666391060 563143316 316559964 210354996 935659060 8961428 828556532 836289720 103290260 269159348 37900652 666669776 660226240 97772628 679939492 518728268 243286000 552372596 587448296 377414532 196041276 148276912 337147156 607572536 386980632 778921464 893185576 106644300 310853372 656413972 247121888 790414956 321907532 985209096 798653612 740647616 285154812 45785008 336202356 884724892 344034748 718874700 183749428 499879508 583659648 883340760 7260788 339835112 18168504 606537980 210047936 996428596 649540552 550752264 811980016 365954108 17426836 114977436 164347960 816661500 965680080 816637880 87190868 924226980 421461108 263929880 215234888 245161428 867515360 806519072 319526636 617837788 261511192 335318968 405843564 863792848 143226956 955452620 526173292 301443164 686321616 915256104 398837872 664543976 60396340 328105420 515114408 90039440 410175472 551021532 177041348 23742824 705557744 690752728 546798276 86789328 501471496 491995152 46044828 261171064 466792612 865895028 586045268 234839488 628428996 401757304 97744284 187429424 476396504 577315316 574173856 332470396 59016932 989125292 482594392 525681996 991005444 399447268 228759700 570512756 761286772 934600884 355065288 906134060 560625424 725252100 260396328 433790748 503356372 726244140 495188576 769426224 948848468 445525164 819656516 831749956 600401504 990755072 884762684 16...

如果我们要保证正确性,则需要加check,但明显复杂度上天。
如果我们要压缩时间而不用gcd,应该还是数论的方向走。
本次仅为班级作业而言,我就不做过多强求。

#include<iostream>
#include<algorithm>using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
int cnt; int n;
int stepNum;void check(int k)
{int step = 0, num = a[0];while (num < a[n - 1])//小于等差数列最大值step++, num += k;//项+1,数量加等差if (num == a[n - 1])b[cnt++] = step, stepNum++;//如果最后一项相等,则表明正确
}int main()
{scanf("%d",&n);for (int i = 0; i < n; i++)scanf("%d",&a[i]);sort(a, a + n);int min_a_d=a[1]-a[0];for(int i=2;i<n;i++)min_a_d=min(min_a_d,a[i]-a[i-1]);//找最小公差for (int i = 1; i <= min_a_d; i++)check(i);//判断是否存在比最小公差小但是符合条件的情况sort(b, b + stepNum);printf("%d",b[0]+1);//输出多个情况中项最少的那一类return 0;
}

自学题目

第三周

上课题目

例1 输入n的值,求n!

思路
代码
解法1.递推
#include<iostream>using namespace std;int main()
{int n;cin>>n;int res=1;for(int i=1;i<=n;i++)res*=i;cout<<res;return 0;
}
解法2.递归
#include<iostream>using namespace std;int func(int num,int sum)
{if(!num)return sum;func(num-1,sum*num);}int main()
{int n;cin>>n;cout<<func(n,1);return 0;
}

例2 输入n的值,求得并输出第n个fibonacci数列的数值。

已知某个数列的第1个数和第2个数的值都是1,从第3个数值开始,每个数值等于其前2个之和。

思路
代码
解法1.递推
#include<iostream>using namespace std;const int N=1e5+10;
int f[N]={0,1,1};int main()
{int n;cin>>n;for(int i=3;i<=n;i++)f[i]=f[i-1]+f[i-2];cout<<f[n];return 0;
}
二叉树递归
#include<iostream>using namespace std;int fib(int n)
{if(n==1||n==2)return 1;else return fib(n-1)+fib(n-2);
}int main()
{int n;cin>>n;cout<<fib(n);return 0;
}

例3 选择法排序

思路: 在n个数值中,求得最小的元素并把其放在开头上。
【在n个数值中,求得最大的元素并把其放在尾巴处】

1 要求得n个数值中的最小值和最小值的位置

     min where

2 在和开头的数值进行交换【目的:最小值在最前面】

3 抛开开头的数值,剩下所有数值重复1,2步骤。【无论数据多少,都是同一种处理方法】

4 考虑一个什么是结束

思路

有n个数,乱序。
第一次,遍历找到最小数字,与第一个交换。
第二次,从第二个数字出发,遍历找到最小数字,与第二个交换。
第三次,从第三个数字出发,遍历找到最小数字,与第三个交换。

直到用来记录出发位置的数字(begin)累加到等于数组长度(n-1),完成。

测试数据
500 218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 10167 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 109 21 365 376 32 19 272 201 238 159 337 304 277
代码
#include<iostream>using namespace std;void func(int a[],int begin,int len)
{if(begin == len-1)return; int tmpIdxNum=a[begin],idx=begin;for(int i=begin+1;i<len;i++)if(tmpIdxNum>a[i]){tmpIdxNum=a[i];idx=i;}swap(a[idx],a[begin]);func(a,begin+1,len);
}int main()
{int n;cin>>n;const int len = n;int a[len+10];for(int i=0;i<len;i++)cin>>a[i];func(a,0,len);for(int i=0;i<len;i++)cout<<a[i];return 0;
}

例4 冒泡法排序:

思路
测试数据
500 218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 10167 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 109 21 365 376 32 19 272 201 238 159 337 304 277
代码
#include<iostream>
#include<algorithm>
#include<cstring>using namespace std;void func(int a[],int len)
{if(!len)return ;for(int i=0;i<len-1;i++)if(a[i]>a[i+1])swap(a[i],a[i+1]);func(a,len-1);
}int main()
{int n;cin>>n;const int len = n;int a[len+10];memset(a,0,sizeof a);for(int i=0;i<n;i++)cin>>a[i];func(a,len);for(int i=0;i<n;i++)cout<<a[i];return 0;
}

作业题目

1137. 第 N 个泰波那契数

泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

示例 1:

输入:n = 4

输出:4

解释:

T_3 = 0 + 1 + 1 = 2

T_4 = 1 + 1 + 2 = 4

示例 2:

输入:n = 25

输出:1389537

提示:

0 <= n <= 37

答案保证是一个 32 位整数,即 answer <= 2^31 - 1。

纯递推过不了34/39,复杂度太高,只能加记忆化。

AC截图

AC代码
解法1.递推
class Solution {public:int tribonacci(int n) {int dp[1000]={0,1,1};if(n==0)return 0;else if(n==1||n==2)return 1;for(int i=3;i<=n;i++)dp[i]=dp[i-1]+dp[i-2]+dp[i-3];return dp[n];}
};
解法2.记忆化搜索
class Solution {public:int dp[38]={0,1,1};int tribonacci(int n) {if(n==0)return 0;return dp[n]?dp[n]:dp[n] = tribonacci(n-1)+tribonacci(n-2)+tribonacci(n-3);}
};

面试题10- II. 青蛙跳台阶问题

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。
求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2

输出:2

示例 2:

输入:n = 7

输出:21

提示:

0 <= n <= 100

思路
AC截图

AC代码
解法1.记忆化递推
class Solution {public:
int dp[101]={1,1,2};int numWays(int n) {return dp[n]?dp[n]:(dp[n] = ((numWays(n-1)+numWays(n-2))%(1000000007)));}
};

面试题 16.11. 跳水板

你正在使用一堆木板建造跳水板。
有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。
你必须正好使用k块木板。

编写一个方法,生成跳水板所有可能的长度。

返回的长度需要从小到大排列。

示例:

输入:

shorter = 1

longer = 2

k = 3

输出: {3,4,5,6}

提示:

0 < shorter <= longer
0 <= k <= 100000

思路

1.公式枚举可能直接放入set去重
3.放入vec数组
4.vec排序

AC截图

AC代码
解法1.枚举

枚举 时间75.46% 空间 100%

class Solution {public:vector<int> divingBoard(int shorter, int longer, int k) {if(!k)return {};if(shorter == longer)return{k*shorter};vector<int>a(k+1);for(int i=0;i<=k;i++)a[i]=shorter*(k-i)+longer*i;return a;}
};
解法2.递归
cclass Solution {public:
vector<int> ans;
set<int> Set;void dfs(int shorter, int longer, int k,int u){if(u<0)return;int t = shorter*(k-u)+longer*u;if(!Set.count(t)&&t)Set.insert(t);dfs(shorter,longer,k,u-1);}vector<int> divingBoard(int shorter, int longer, int k) {dfs(shorter,longer,k,k);for(auto op:Set)ans.push_back(op);   sort(ans.begin(),ans.end());return ans;}
};

自学题目

P62页,例2.12 拆分输出

【例2.12】设计一个递归算法,输出一个大于零的十进制数n的各数字位,如n=123,输出各数字位为123。

思路

直接压递归,利用回溯的思路输出

代码
解法1.递归
#include<iostream>using namespace std;void func(int n)
{if(n)func(n/10),cout<<n%10<<endl;
}int main()
{int n;cin>>n;func(n);return 0;
}

P66页 n皇后的问题

P66页,求解n皇后的问题

提醒大家:书上某些程序是有错的,是不能直接执行。

n-皇后问题是指将 n 个皇后放在 n∗n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

现在给定整数n,请你输出所有的满足条件的棋子摆法。

输入格式
共一行,包含整数n。

输出格式
每个解决方案占n行,每行输出一个长度为n的字符串,用来表示完整的棋盘状态。

其中”.”表示某一个位置的方格状态为空,”Q”表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围
1≤n≤9
输入样例:
4
输出样例:

.Q..
...Q
Q...
..Q...Q.
Q...
...Q
.Q..
思路

标准的DFS结构,值得注意的地方自我感觉有两点
1.分为选择和不选择两种情况
2.需要用数组构建反对角线和对角线
2.1.反对角线 y=x+b b=y-x 因为不可能是负数可以写为 b=n-x+y dg[x+y],
2.2.由反对角线我们的到对角线 udg[len-x+y]

代码
解法1.DFS 深度优先搜索
#include<iostream>using namespace std;const int N=2*10;
char g[N][N];
bool col[N],row[N],dg[N],udg[N];void dfs(int x,int y,int s,int len)
{if(x==len)x=0,y++;if(y==len){if(s==len){for(int i=0;i<len;i++)cout<<g[i]<<endl;cout<<endl;}return ;}g[x][y]='.';dfs(x+1,y,s,len);if(!col[x]&&!row[y]&&!dg[x+y]&&!udg[len-x+y])//行 列 对角线 反对角线 都被标记{g[x][y]='Q';col[x]=row[y]=dg[x+y]=udg[len-x+y]=true;dfs(x+1,y,s+1,len);col[x]=row[y]=dg[x+y]=udg[len-x+y]=false;g[x][y]='.';}
}int main()
{int n;cin>>n;dfs(0,0,0,n);return 0;
}
了解更多

如果你对这个写法并不够清晰或者想了解更多可以查看我写的另一篇文章n皇后问题

hanoi 汉诺塔问题

思路

我们可以直接利用递归的思路
把现有的拆分掉

假设我们有N个块
n-1被拿去,想办法给到b,然后想办法再送到c
轮到第n个被拿去直接丢给c

这样我们的思路就十分清晰了

代码
解法1.递归
#include<iostream>using namespace std;void hanoi(int n,char a,char b,char c)
{if(!(n-1)){cout<<a<<"->"<<c<<endl;return ;}//剩下的这一个直接给chanoi(n-1,a,c,b);//n-1从a到bcout<<a<<"->"<<c<<endl;hanoi(n-1,b,a,c);//n-1从b到c
}
int main()
{int n;cin>>n;hanoi(n,'a','b','c');return 0;
}
了解更多

如果你对这个写法并不够清晰或者想了解更多可以查看我写的另一篇文章hanoi问题

第四周

上课题目

题目计分

1 某电视台举办了低碳生活大奖赛。题目的计分规则相当奇怪:每位选手需要回答10个问题(其编号为1到10),越后面越有难度。答对的,当前分数翻倍;答错了则扣掉与题号相同的分数(选手必须回答问题,不回答按错误处理)。每位选手都有一个起步的分数为10分。某获胜选手最终得分刚好是100分,如果不让你看比赛过程,你能推断出他(她)哪个题目答对了,哪个题目答错了吗?如果把答对的记为1,答错的记为0,则10个题目的回答情况可以用仅含有1和0的串来表示。例如:0010110011 就是可能的情况。

两种方法来完成,做对比
方法1:直观的思考方法是枚举法。暴力破解。
涉及到编号很容易联想到一个知识点:数组,因为数组有编号。数组的编号实际是从0开始的。所以因为是10道题目,且编号是1-10,所以我准备定义数组长度是11,可以废掉第0个不适用。使用的编号范围是1-10的数组元素。其中数组元素的值就是0或者1。
因为枚举会涉及到for循环。刚好虽然这里是有2个数值0和1,那可以用循环来表示,0到1的取值范围。

思路
代码
解法1.二进制枚举写法

用二进制枚举,用01表示和查找所有可能

#include<iostream>using namespace std;int main()
{for(int i=0;i<=1<<10;i++)//二进制状态下左移10个位置 INT为1024{int tmpNum=10;for(int j=0;j<10;j++)if(i>>j&1)tmpNum*=2;//检查 i向右移动j位之后,当前这个数字是否是1else tmpNum-=j+1;if(tmpNum==100){for(int j=0;j<10;j++)if(i>>j&1)cout<<1;else cout<<0;cout<<endl;}}}
解法2.dfs版本

正常的dfs思路

#include<iostream>using namespace std;const int N=10;
bool st[N+5];void dfs(int sum,int u)
{if(u>N)//表明十道题都答完了{if(sum==100){for(int i=1;i<=10;i++)if(st[i])cout<<1;else cout<<0;cout<<endl;}return ;}if(st[u]==false)//选择的状态{st[u]=true;dfs(sum*2,u+1);st[u]=false;}st[u]=false;//不选的状态dfs(sum-u,u+1);
}int main()
{dfs(10,1);return 0;
}
答案
0010110011
0111010000
1011010000

打印图形 我觉得不考 待补

rank=3

rank=5

rank=6

思路
代码
了解更多

我做过原题,其实是程序理解题,你可以查看我写的打印图形

下课题目

看图写码 我觉得不考 待补

思路
代码

图选数字

在一个由 n 行 m 列的方格组成的地图上,每个方格上有一个数,你要取出一些数,使得他们的和值最大。
但是有一个条件,你选取的数中,任意 2 个数所在的方格都不能相邻。
2 个方格相邻就是指他们共享一条边。

数据
6 4
48  30  39  87
48  91  90  22
36  60  41  28
49  96  37  88
87  71  96  66
15  24  75  55
答案

749

代码

本来我全部局部数据,结果到最后数组需要静态数据我拿不出来局部的,吐了
而且写了6个参数,太烦了,还是老老实实全局走起来

正常dfs思路

解法1. DFS深度优先搜索
#include<iostream>
#include<cstring>using namespace std;int dx[]={-1,0,1,0},dy[]={0,1,0,-1};//上下左右四个偏移量const int N=1e4;//我没有给固定数字,相当于把这道题转换为自由给定数据的题目,但是最大NM只能在1e4左右,毕竟最大也就2E9
int g[N][N];
bool st[N][N];void dfs(int x,int y,int tmpn,int &sum,int row,int col)
{if(y==col)x++,y=0;//是这样的,我把y理解成列,col就是列的数量,走完了就加一个行数,我看行if(x==row){sum = max(sum,tmpn);return ;}else {bool f = true;for(int i=0;i<4;i++)//判断一下合法{int tmpx=x+dx[i],tmpy=y+dy[i];if(tmpx<0||tmpx>=row||tmpy<0||tmpy>=col)continue;//边界if(st[tmpx][tmpy]){f=false;break;}//四周是否有目标值}if(f){st[x][y]=true;   dfs(x,y+1,tmpn+g[x][y],sum,row,col);//选择st[x][y]=false;}dfs(x,y+1,tmpn,sum,row,col);//不选}
}int main()
{int n,m;cin>>n>>m;for(int i=0;i<n;i++)    for(int j=0;j<m;j++)cin>>g[i][j];int res=0;dfs(0,0,0,res,n,m);cout<<res;return 0;
}
吐槽

这个思路其实和N皇后非常相似
但是给半截属实不必

了解更多

首先你可能需要更加详细的了解这道题,因此你可以我写的详细解析图解数字
其次你可能需要了解与这个思路非常密切的N皇后问题,因此你也可以查看我写的N皇后问题
同样他也有非常多的变体,如果你又双叒叕有兴趣的话,也可以看我写的另另另一篇变体解析八皇后问题

自学题目

第五周

上课题目

快速排序

快速排序诞生于1962年
它是对冒泡法排序的改进。
现在网上对于快速排序的算法的具体的描述有多种版本。【写法不是唯一】

快速排序的思想

(1)通过一趟排序要将排序的数据分割成独立的2部分。
(2)其中一部分的所有数值都要比另外一部分所有数值都小
【一边全是小的】【另外一变全是大的】
(3)然后再按照此方法分别对(2)中的2个部分,在分别执行快速排序
(4)整个排序过程可以用递归进行,最后整个数据排列搞定。

详细讨论
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]
7 9 6 4 5 1 8 3 2

1 首先选择一个参考数值,作为关键数据【把它放在它应该放在的位置】
【应该放在的位置:在排序后,它在整个序列中的最后的位置】
【选择关键数据:其实可以任意选择,我们定为选择数组中首个数值作为关键数据】

a[0]的标号作为key
目的:让7放在a[6]上

2 要把7与整个数组中所有的值要进行比较。才能确定7所放的位置
整个快速排序的最关键的步骤:【核心思想】
讨论将比7小的放在7的左边,比7大的放在7的右边
具体如下

思路
代码
#include<iostream>using namespace std;const int N=1e5;
int a[N];void quickSort(int l,int r)
{if(l==r)return ;int mid = l+r>>1;int X=a[mid];int i=l-1,j=r+1;//因为dowhile所以...while(i<j){do i++;while(a[i]<X);do j--;while(a[j]>X);//找逆序元素if(i<j)swap(a[i],a[j]);//交换}quickSort(l,j);//分治quickSort(j+1,r);
}
int main()
{int n;cin>>n;for(int i=0;i<n;i++)cin>>a[i];quickSort(0,n-1);for(int i=0;i<n;i++)cout<<a[i];return 0;
}
测试数据
500 218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 10167 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 109 21 365 376 32 19 272 201 238 159 337 304 277
了解更多

如果你想了解更多的快速排序的逻辑,可以直接参照我写的快速排序,或者在B站查询更多优质UP主的视频,而视频方式的内容或许能让你理解得更快
如果你想了解颜老师要求的六种排序算法,你可以查看我的六种排序

下课题目

自学题目

第六周

上课题目

归并排序

【第4个排序,记得一共是6个】

思路:
1 将所有的数据一分为二(分成2部分)
注意: 如果是偶数个数值,刚好能均分为2部分
如果是奇数个数值,只能分成一边多一边少
【定:左多右少?左少右多?】
2 继续分,把左边的数据再分成2部分;右边的数据也再分成2部分。
3 层层往下分,分到最后就剩下每次只有1个数值
4 归:每次2组数值合并为1数组,并且合并后的数值是从小到大的(有序的)

思路
代码
#include<iostream>using namespace std;const int N=1e5;
int a[N],t[N];void mergeSort(int l,int r)
{if(l==r)return ;int mid = l+r>>1;mergeSort(l,mid);mergeSort(mid+1,r);int i=l,j=mid+1;int idx=0;while(i<=mid&&j<=r)if(a[i]<=a[j])t[idx++]=a[i++];else t[idx++]=a[j++];while(i<=mid)t[idx++]=a[i++];while(j<=r)t[idx++]=a[j++];for(int i=0,j=l;j<=r;j++,i++)a[j]=t[i];
}
int main()
{int n;cin>>n;for(int i=0;i<n;i++)cin>>a[i];mergeSort(0,n-1);for(int i=0;i<n;i++)cout<<a[i]<<" ";return 0;
}
了解更多

如果你想了解更多的[归并排序的逻辑,可以直接参照我写的归并排序,或者在B站查询更多优质UP主的视频,而视频方式的内容或许能让你理解得更快
如果你想了解颜老师要求的六种排序算法,你可以查看我的六种排序

例2 折半查找

查找分类
(1)顺序查找
(2)折半查找

(1)顺序查找
思路:将所要查询的数据和已经存在的所有数据进行依次比对,如果相同则找到

(2)折半查找
提前:必须是对有序(升序还是降序)的数据进行查询。否则不能进行折半查找!【灵魂所在】

思路:
对有序的数值,求中间值,判断这个中间是否是所要查询的对象,如果是则输出,
如果不是所要查找的对象
则立即比较大小
如果中间值小于查找值,则继续再右边进行查找
如果中间值大于查找值,则继续再左边进行查找
一直重复下去。【明显能体现出 分治法的思路】
举例说明

假设找8                                   a[0]    a[1]    a[2]    a[3]    a[4]    a[5]    a[6]    a[7]    a[8]
原始数据            1       2       3       4       5       6       7       8       9
第1次折半查找     1       2       3       4       5       6       7       8       9
第2次折半查找                                             6       7       8       9
第2次折半查找                                                             8       9找到了    一共进行3次
思路

简单的递归,二分

代码
#include<iostream>
#include<algorithm>using namespace std;const int N=1e5;
int a[N],t[N];int binnarySearch(int l,int r,int x)
{int mid = l+r>>1;int midNum = a[mid];if(midNum == x)return mid+1;if(x>midNum)binnarySearch(mid+1,r,x);else binnarySearch(l,mid-1,x);
}
int main()
{int n,x;cin>>n>>x;for(int i=0;i<n;i++)cin>>a[i];sort(a,a+n);cout<<binnarySearch(0,n-1,x);return 0;
}
测试数据
500 277218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 10167 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 109 21 365 376 32 19 272 201 238 159 337 304 277

例3 最重要的程序 我觉得不考 待补

大家是否知道在2019年国庆阅兵典礼中最后一个出场的是谁?
中国女排!
在2019年9月30日那天,获得了女排世界杯冠军!!!

是11连胜夺冠!!!

女排世界杯的赛制

比赛赛制采用12支队伍单循环,
两两捉对厮杀一场定胜负,依次进行。
比赛开始把12个队分成AB两个组进行,
当同组每一个选手都碰面以后,

再重新分组进行比赛,
确保12支队伍每两支都相遇一次,
最终将根据先胜负场次后积分的排名顺序。

今天我们所要编写的程序就是输入球队的数量,得出比赛的对阵表!【分组处理】

为了方便起见,借用百度中对象 对球名称和对应的编号【编号是种子队编号】
提醒:
1 题目给与12个队伍,最终是考虑任意个队伍
2 如果12个队伍,比赛一共是进行了11天
3如果12个队伍,每天的比赛场数应该是6场

1 先分析2个队伍的时候,比赛对阵表,如何表示?

作业题目

硬币称重

关于硬币:关于一个硬币的问题。
如果有16个硬币,都是一元的 重量是6g,其中有1个是假硬币重量是5g,要求找出假的那个?
模仿实现 :
(1)需要一个数组 int a[17];
(2)所有数组一开始全部给初始值6
(3)利用随机函数 生成标号i 范围在1-16之间 a[i]=5
(4)利用分治法方法 来解决问题

思路

首先考虑的是折半查找,但是这样操作必须要解决的是需要排序为前提,而排序就违背了题目本意。
其次从归并考虑,发现想从逆序对处理,返现递归到底合并时候又难计算总的位次,
于是我们从特性入手,
因为5是奇数,所以二分两边的块是否%2!=0,否就二分检索另一块
我们把数组设置为a1到a17,这样中间数就是1+17>>1=9,初次只计算1-8和10-17,以此类推所有的递归都不重不漏。
这样只要检测到mid是奇数,返回即可

代码
解法1.二分递归+位运算
#include<iostream>
#include<cstdlib>
#include<ctime>using namespace std;
int a[18];int search(int l, int r)
{int mid = l + r >> 1;if (a[mid] & 1)return mid;int p1 = 0, p2 = 0;for (int i = l; i < mid; i++)p1 += a[i];for (int i = mid + 1; i <= r; i++)p2 += a[i];if (p1 & 1)search(l, mid);else search(mid + 1, r);
}int main()
{for (int i = 1; i < 18; i++)a[i] = 6;srand(time(NULL));a[rand() % 17 + 1] = 5;cout << search(1, 17);return 0;
}

自学题目

折半思考题

注意:上述折半查找的算法是查找出的值是唯一的。
但是大多数据中体现出的是数据非唯一。
下来思考并修改该程序,改为可以查找非唯一性数值。

代码
解法1.二分递归
#include<iostream>
#include<algorithm>using namespace std;const int N=1e5;
int a[N],findArr[N];
int idx =0;void binnarySearch(int l,int r,int x)
{int mid = l+r>>1;int midNum = a[mid];//cout<<l<<" "<<mid<<" "<<midNum<<" "<<r<<endl; if(midNum == x)findArr[idx++]=mid+1;if(l==r)return ;if(x>=midNum)binnarySearch(mid+1,r,x);if(x<=midNum)binnarySearch(l,mid-1,x);
}
int main()
{int n,x;cin>>n>>x;for(int i=0;i<n;i++)cin>>a[i];sort(a,a+n);binnarySearch(0,n-1,x);for(int i=0;i<idx;i++)cout<<findArr[i]<<" ";return 0;
}
测试数据

1 3 2 2 2 2
2 6 2 1 2 2 2 3 3
8 2 1 2 2 2 2 4 5 6

注意

强制修改了
结束条件,
分治条件

因为存在N个相同的情况,所以需要两边一起判断,同时结束条件也可能有问题,

! 最大测试数据只通过到了8

P91页 查找最大值和次大值

事实上在46页

思路

&方便传回值
&同时传值给lmaxFis,lmaxSec,rmaxFis,rmaxSec
分治细化到元素数量为1,更新最大值,
分治细化到元素数量为2,更新最大最小值,
分治细化到元素数量 >2, 比较更新两块的最大最小值

代码
解法1.二分递归
#include<iostream>using namespace std;int nums[]={2,5,1,4,6,3};
int a,b;void get(int l,int r,int &a,int &b)
{if(l==r){if(nums[l]>a)b=a,a=nums[l];else b=max(nums[l],b);return ;}int mid = l+r>>1;get(l,mid,a,b),get(mid+1,r,a,b);
}int main()
{get(0,sizeof nums/4,a,b);cout<<a<<" "<<b;return 0;
}
了解更多

这道题目的原本代码十分繁杂,宛如裹脚布一般,如果你希望更深一步了解你可以查看我写的[分治]查找最大和次大元素,或者在B站寻找优质视频进行学习

P96 寻找2个等长有序序列的中位数

事实上在第50页

对于一个长度为n的有序序列(假设均为升序序列)a[0…n-1],处于中间位置的元素称为a的中位数。
设计一个算法求给定的两个有序序列的中位数。

思路
代码

代码如果是单纯为了方便那肯定走这个
但是空间上可能相对较大,如果N存在1E9的数量级那应该就过不了
如果之后有时间再更新另一个方法,有就先用着好了

#include<iostream>
#include<algorithm>using namespace std;const int N=1e5;
int t[N];int main()
{int n;cin>>n;for(int i=0;i<2*n;i++)cin>>t[i];sort(t,t+n);cout<<t[(0+n-1)>>1];return 0;
}

第七周

上课题目

插入排序

例1 插入排序
分析:
基本思想:
举例说明:

插入排序的思想:
把某个位置上的的数值,插入到它最合适的位置

考虑第0个数值6,不管其他,它就在这个位置就好了

考虑第1个数值4,由于6>4,所以4插入到6之前

考虑第2个数值7,由于6<7,所以7就站在原位就好了
而4就没必要判断

考虑第3个数值4, 由于7>3,所以3插入到7之前
由于6>3,所以3插入到6之前
由于4>3,所以3插入到4之前
因为3之前没有数据的了所以停止

思路
代码
#include<iostream>using namespace std;const int N=1e5;
int n;
int a[N];void insertSort()
{for(int i=0;i<n-1;i++)for(int j=i+1;j;j--)if(a[j]<a[j-1])swap(a[j],a[j-1]);else break;
}int main()
{cin>>n;for(int i=0;i<n;i++)cin>>a[i];insertSort();for(int i=0;i<n;i++)cout<<a[i];return 0;
}
测试数据
500 218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 10167 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 109 21 365 376 32 19 272 201 238 159 337 304 277
了解更多

如果你想了解更多的插入排序的逻辑,可以直接参照我写的插入排序,或者在B站查询更多优质UP主的视频,而视频方式的内容或许能让你理解得更快
如果你想了解颜老师要求的六种排序算法,你可以查看我的六种排序
虽然是排序算法,但是此排序算法已经能证明它的思想是 蛮力法。一一比较。

例2 1,2,3,4可以组成那些没有重复的4位数值

分析:当初在大家大一的时候我教过你们的。还记得吗

思路

没有必要看这个,直接是全排列的概念,nextpermutation即可

代码
全排列
#include<iostream>
#include<algorithm>using namespace std;const int N=1e5;
int a[N];int main()
{int n;cin>>n;for(int i=0;i<n;i++)cin>>a[i];do{for(int i=0;i<n;i++)cout<<a[i]<<" ";cout<<endl;}while(next_permutation(a,a+n));return 0;
}
测试数据
4 1 2 3 4
输出数据
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1

例3 0/1背包问题

【算法中非常经典的一个例子。】
【回朔法,动态规划等】

有n个重量分别是w1,w2…,wn的物品(物品编号为1-n)
它们的价值分别为v1,v2,…,vn
给定一个容量为W的背包。
设计从这些物品中选取一部分放入该背包的方案。
每个物品要么选中要么不选中,【意味着:说明每个物品只有1样】
要求选中的物品不仅能够放在背包中,而且具有最大的价值。
并对如下所展示的5个物品求出W不超过10时的最佳解。
物品编号 重量 价值
1 2 6
2 2 3
3 6 5
4 5 4
5 4 6

思路
代码
方法一:字符串蛮力
#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;int main()
{int W = 10, n = 5;int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };string pres = "00000";int ww = 0, vv = 0, maxv = 0;string str;char s[1000];for (int j = 0; j < 5; j++)for (int a = 0; a < 5; a++)for (int b = 0; b < 5; b++)for (int c = 0; c < 5; c++)for (int d = 0; d < 5; d++)for (int e = 0; e < 5; e++){if (a != b && a != c && a != d && a != e);if (b != c && b != d && b != e);if (c != d && c != e);if (d != e);pres[j]='1';s[0] = pres[a]; s[1] = pres[b]; s[2] = pres[c]; s[3] = pres[d]; s[4] = pres[e];//cout << s[0] << " " << s[1] << " " << s[2] << " " << s[3] << " " << s[4] << " " << endl;for (int i = 0; i < 5; i++)ww += (s[i] - '0')*w[i], vv += (s[i] - '0')*v[i];//当前背包重量不超过容量,且vv当前背包价值大于最大价值if (ww <= W && vv > maxv)maxv = vv, str = s;//记录此时的s的组合vv = 0, ww = 0;}for (int i = 0; i < 5; i++)cout << str[i];cout << endl;cout << maxv << endl;return 0;
}
方法二:二进制枚举
#include<iostream>using namespace std;int ww,vv,maxv,strres;int main()
{int W = 10;int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };for(int i=0;i<1<<5;i++)//二进制最大可能选择数{for(int j=0;j<5;j++)ww += (i>>j&1)*w[j], vv += (i>>j&1)*v[j];/判断当前位子是否被选择,更新0或1倍目标值的数值if (ww <= W && vv > maxv)maxv = vv,strres=i;//更新vv = 0, ww = 0;}for(int i=0;i<5;i++)cout<<(strres>>i&1);//因为是选择情况,所以直接输出cout<<endl;cout << maxv;return 0;
}
方法三:DFS

无法保存最大路径

#include<iostream>using namespace std;int ww,vv,maxv,strres;
int W = 10;
int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };int str[5];
int ans[5];void dfs(int tw,int ans)
{if(tw<=W&&ans > maxv){maxv = ans;return ;}for(int i=0;i<5;i++)if(!str[i]&&tw>=w[i]){str[i]=1;dfs(tw-w[i],ans+v[i]);str[i]=0;}}
int main()
{dfs(W,0);cout << maxv;return 0;
}
方法三.2闫老板思考角度
#include<iostream>using namespace std;int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };int x[5];
int maxv = 0;
int ans[5];void dfs(int i, int ww, int vv)
{if (i == 5)if (ww <= 10 && vv > maxv) { maxv = vv; for(int i=0;i<5;i++)ans[i]=x[i];return; }//记录最优状态else return;//这里给他加了个退出x[i] = 1;dfs(i + 1, ww + w[i], vv + v[i]);x[i]=0;dfs(i + 1, ww, vv);
}int main()
{dfs(0, 0, 0);for(auto x:ans)cout<<x;cout<<endl;cout << maxv;return 0;
}
方法四:全排列

利用next_permuatation的特性,全排列,而我们只需要截取前面五位的状态即可

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;int main()
{int W = 10, n = 5;int w[5] = {2, 2, 6, 5, 4}, v[5] = {6, 3, 5, 4, 6};string s = "0000011111";int ww = 0, vv = 0, maxv = 0;string str;for (int j = 0; j < n; j++){do{for (int i = 0; i < n; i++)ww += (s[i] - '0') * w[i], vv += (s[i] - '0') * v[i];//当前背包重量不超过容量,且vv当前背包价值大于最大价值if (ww <= W && vv > maxv)maxv = vv, str = s; //记录此时的s的组合vv = 0, ww = 0;} while (next_permutation(s.begin(),s.end()));}for(int i=0;i<5;i++)cout << str[i];cout<<endl;cout << maxv;return 0;
}
方法五:数组蛮力

利用数组表示01

#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;
int s[5];int main()
{int W = 10, n = 5;int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };int ww = 0, vv = 0, maxv = 0;string str;for (s[0]=0; s[0] < 2; s[0]++)for (s[1]=0; s[1] < 2; s[1]++)for (s[2]=0; s[2] < 2; s[2]++)for (s[3]=0; s[3] < 2; s[3]++)for (s[4]=0; s[4] < 2; s[4]++){for (int i = 0; i < 5; i++)ww += (s[i])*w[i], vv += (s[i])*v[i];if (ww <= W && vv > maxv)maxv = vv;vv = 0, ww = 0;}cout << maxv << endl;getchar(); getchar();return 0;
}
答案

11001
15

了解更多

如果你对下课部分的内容有更多的疑惑,或者说不大看的明白我的写法,请看我写的五种蛮力法解决01背包问题

下课题目

01背包问题 枚举法【蛮力法】

思路
代码
方法一:字符串蛮力
#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;int main()
{int W = 10, n = 5;int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };string pres = "00000";int ww = 0, vv = 0, maxv = 0;string str;char s[1000];for (int j = 0; j < 5; j++)for (int a = 0; a < 5; a++)for (int b = 0; b < 5; b++)for (int c = 0; c < 5; c++)for (int d = 0; d < 5; d++)for (int e = 0; e < 5; e++){if (a != b && a != c && a != d && a != e);if (b != c && b != d && b != e);if (c != d && c != e);if (d != e);pres[j]='1';s[0] = pres[a]; s[1] = pres[b]; s[2] = pres[c]; s[3] = pres[d]; s[4] = pres[e];//cout << s[0] << " " << s[1] << " " << s[2] << " " << s[3] << " " << s[4] << " " << endl;for (int i = 0; i < 5; i++)ww += (s[i] - '0')*w[i], vv += (s[i] - '0')*v[i];//当前背包重量不超过容量,且vv当前背包价值大于最大价值if (ww <= W && vv > maxv)maxv = vv, str = s;//记录此时的s的组合vv = 0, ww = 0;}for (int i = 0; i < 5; i++)cout << str[i];cout << endl;cout << maxv << endl;return 0;
}

自学题目

第八周

上课题目

例1 0/1背包问题

【算法中非常经典的一个例子。】
【回朔法,动态规划等】

有n个重量分别是w1,w2…,wn的物品(物品编号为1-n)
它们的价值分别为v1,v2,…,vn
给定一个容量为W的背包。
设计从这些物品中选取一部分放入该背包的方案。
每个物品要么选中要么不选中,【意味着:说明每个物品只有1样】
要求选中的物品不仅能够放在背包中,而且具有最大的价值。
并对如下所展示的5个物品求出W不超过10时的最佳解。

物品编号   重量  价值
1           2       6
2           2       3
3           6       5
4           5       4
5           4       6
思路
代码
解法1.DFS深度优先搜索
#include<iostream>using namespace std;int ww,vv,maxv,strres;
int W = 10;
int w[5] = { 2,2,6,5,4 }, v[5] = { 6,3,5,4,6 };int str[5];
int ans[5];void dfs(int tw,int ans)
{if(tw<=W&&ans > maxv){maxv = ans;return ;}for(int i=0;i<5;i++)if(!str[i]&&tw>=w[i]){str[i]=1;dfs(tw-w[i],ans+v[i]);str[i]=0;}}
int main()
{dfs(W,0);cout << maxv;return 0;
}
了解更多

如果对这道题的更多做法有兴趣可以请看我写的五种蛮力法解决01背包问题

例1 求迷宫问题

有如下8*8的迷宫

其中,O表示通路方块,X表示障碍方块。
假设入口位置是(0,0),出口位置为右下角方块位置是(7,7)。
设计一个程序求指定入口到出口的一条迷宫路径。

分析:
1 如何凸显这个答案,通路,把可以通路的方块以空格去填充方案。
2 要讨论上下左右是否有通路的问题。
需要用到上下左右坐标的变化【行号的变化,列号的变化】
我们讨论的时候稍微讲究一下4个方位的顺序问题【上开始,做顺时针】
【上,右,下,左】
int X[4]={-1,0,+1,0};
int Y[4]={0,+1,0,-1};
3 采用深度优先算法的思路来完成接下来详细分析【注意过程】
【一道条走到黑,如果没有答案则返回】
返回的过程要把刚才填写了空格的地方【补大写的O】
【补的是你之前修改过的值】
【整个过程避免了重复】

思路
代码
解法1.DFS深度优先搜索
#include<iostream>using namespace std;const int N=1e4;char g[N][N];int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
int n,m;void SearchDFS(int x,int y)
{if(x==n-1&&y==m-1){g[x][y]=' ';for(int i=0;i<n;i++)cout<<g[i]<<endl;return ;}   for(int i=0;i<4;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<0||tx>=n||ty<0||ty>=m)continue;if(g[tx][ty]=='O'){g[tx][ty]=' ';SearchDFS(tx,ty);g[tx][ty]='O';}}
}int main()
{cin>>n>>m;for(int i=0;i<n;i++)cin>>g[i];SearchDFS(0,0);return 0;
}
答案
OXXXXXXXOOOXXX
X XXOOOX
X XXOXXO
X XXXXXX
X XX   X
X    X
XXXXXXX 
测试数据
8 8
OXXXXXXX
OOOOOXXX
XOXXOOOX
XOXXOXXO
XOXXXXXX
XOXXOOOX
XOOOOXOO
XXXXXXXO
注意:

如果递归调用过程中dfs(i+X[k],j+Y[k]); 一直做下去,直到已经有解了,
【如果答案是唯一解,且我在输出中用了return ;】
那回填那个操作轮不到做了tu[i][j]=‘O’;,毕竟它们2个之间的关系是上下代码关系。

像迷宫类的问题的求解方法,挺简单的。

例2 迷宫 我认为不考 待补

试题 E: 迷宫
本题总分:15 分
【问题描述】
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可以通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这个它的上、下、左、右四个方向之一。
对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。
对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式,其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 maze.txt,内容与下面的文本相同)

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个字符串,包含四种字母 D、U、L、R,在提交答案时只填写这个字符串,填写多余的内容将无法得分。

思路
代码
注明

1.这道题颜老师上课没有做出来,所以肯定不会考
2.这道题用dfs做会爆堆栈
3.这道题只能用bfs写,设计最短路径概念和队列使用,但是不会教

综上,肯定不会考,我也没时间写,就先空着了,如果考了我就原地吃屏幕

下课题目

自学题目

第九周

上课题目

数列重组

设计一个算法在1,2,……9(顺序不变)数值之间插入+或者-或者什么都不插入,
使得计算结果总是100的程序。输出所有的情况。例如1+2+34-5+67-8+9=100。
方法1
处理:“什么都不插入”,使用空格来表示!

思路
代码
解法1.DFS深度优先搜索
#include<iostream>using namespace std;const int N=1e4;
int a[N];
char ch[N];
int n,kNum;void func(int sum,int begin,int u)
{if(u == n){if(sum == kNum){cout<<a[1];for(int i=2;i<=n;i++)if(ch[i]=='+'||ch[i]=='-')cout<<ch[i]<<a[i];else cout<<a[i];cout<<endl;}return ;}else {ch[u]='+';sum+=a[u];func(sum,a[u],u+1);sum-=a[u];ch[u]='-';sum-=a[u];func(sum,-a[u],u+1);sum+=a[u];ch[u]=' ';sum-=begin;int tmpN=0;if(begin)tmpN=begin*10+a[u];else tmpN=begin*10-a[u];sum+=tmpN;func(sum,tmpN,u+1);sum-=tmpN;sum+=begin;}
}int main()
{cin>>n>>kNum;for(int i=1;i<=n;i++)cin>>a[i];func(0,1,1);return 0;
}
测试数据

9 100
1 2 3 4 5 6 7 8 9

答案
1+23-4+5+67+89
1-2+34-5-6+789
1-2-3+45+67-89
12+3-4+5+6+789
12+34-5+67-89
123+45-6-789
12-34+56+789
1+2+3-4+5+6+789
1+2+34-5+67-89
1+23-4+56+7+89
12+3-4-5-6-7+89
12+3-45+6+7+89
12+34-56+7-89
12-3+4-5-6+7-89
12-3-4+5+6-7-89

下课题目

自学题目

第十周 我认为不考 待补

上课题目

下课题目

自学题目

第十一周

上课题目

例1 兑换货币

在2006年开始工作的时候,那个时候我们的工资不是打到卡上。
而是到财务处领现金。
假设我某个月的收入是1289,请问财务处给我如何发工资,使得我们拿到手的纸币最少呢?
【最终实现:任意输入某个月的收入,求得答案】
我把它更新为了所有数据都是自己输入的版本,变量名很明显了就不注释了

思路

优先大的原则

代码
解法1.贪心
#include<iostream>
#include<vector>
#include<algorithm>using namespace std;bool cmp(int a,int b){return a>b;}
int main()
{vector<int>a;int sumPrice,n;cin>>sumPrice>>n;for(int i=0;i<n;i++){int t;cin>>t;a.push_back(t);}sort(a.begin(),a.end(),cmp);int res=0;for(int i=0;i<n;i++)res+=(sumPrice/a[i]),sumPrice%=a[i];cout<<res;return 0;
}
测试数据
431 7 100 1 2 5 10 20 50

思考:【LeetCode】柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5 美元。
顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。
你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
示例 1:
输入:[5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
示例 2:
输入:[5,5,10]
输出:true
示例 3:
输入:[10,10]
输出:false
示例 4:
输入:[5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

提示:

0 <= bills.length <= 10000
bills[i] 不是 5 就是 10 或是 20

【我的要求是:输入的多个客户的支付的钱数,任意输入!!!】

思路

模拟整个换钱过程

AC截图

代码

解法1.模拟
class Solution {public:int cnt5,cnt10,cnt20;bool lemonadeChange(vector<int>& bills) {int f=true;for(int x:bills)if(x==5)cnt5++;else if(x==10&&cnt5)cnt10++,cnt5--;else if(x==20&&cnt10&&cnt5)cnt20++,cnt10--,cnt5--;else if(x==20&&cnt5>=3)cnt20++,cnt5-=3;else {f=false;break;}return f;}
};

单调递增的数字【选自LeetCode】

给定一个非负整数 N,找出小于或等于 N 的最大的整数,
同时这个整数需要满足其各个位数上的数字是单调递增。

(当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,
我们称这个整数是单调递增的。)

示例 1:
输入: N = 10
输出: 9

示例 2:
输入: N = 1234
输出: 1234

示例 3:
输入: N = 332
输出: 299
说明: N 是在 [0, 10^9] 范围内的一个整数。

思路

我们拿 321 来举例
这个时候 a1>a2>a3
我们可以直观察觉,直到299为止都不会有正确数据
于是我们粗略的得到 ai>ai+1时,a[0]-=1,a[i]->a[asize]=9

但是此时显然不符合231 这样的数据,因为显然只需要 229即可,所以现在的设想是 a[i]-=1,a[i+1]->a[a.size]=9

以 332来举例 我们简化为 329时,又发现不满足ai>ai+1的情况
于是我们需要把i从头再排查一遍,直接i=-1

AC截图

AC代码
解法1.暴力

暴力 过不了所有数据
但是和颜老板的思路是相同的

class Solution {public:bool check(int n){int pre =n%10;int next = 0;n/=10;while(n){next = n%10;n/=10;if(pre<next)return false;pre = next;}return true;}int monotoneIncreasingDigits(int N) {for(int i=N;i>=0;i--)if(check(i))return i;return 0;}
};
解法2. 贪心

我们拿 321 来举例
这个时候 a1>a2>a3
我们可以直观察觉,直到299为止都不会有正确数据
于是我们粗略的得到 ai>ai+1时,a[0]-=1,a[i]->a[asize]=9

但是此时显然不符合231 这样的数据,因为显然只需要 229即可,所以现在的设想是 a[i]-=1,a[i+1]->a[a.size]=9

以 332来举例 我们简化为 329时,又发现不满足ai>ai+1的情况
于是我们需要把i从头再排查一遍,直接i=-1

class Solution {public:vector<int>a;int monotoneIncreasingDigits(int N) {if(N<10)return N;while(N){a.push_back(N%10);N/=10;}reverse(a.begin(),a.end());for(int i=0;i<a.size()-1;i++){if(a[i]>a[i+1]){a[i]--;for(int j=i+1;j<a.size();j++)a[j]=9;i=-1;//感觉简直神来之笔,本来我用递归,差点没自闭}}for(int i=0;i<a.size();i++)cout<<a[i]<<endl;int res=0;for(int i=0;i<a.size();i++)res=res*10+a[i];return res;}
};

下课题目

自学题目

组队 贪心版本

#include<stdio.h>
int a[21][6]={0,0,0,0,0,0,
1,97,90,0,0,0,
2,92,85,96,0,0,
3,0,0,0,0,93,
4,0,0,0,80,86,
5,89,83,97,0,0,
6,82,86,0,0,0,
7,0,0,0,87,90,
8,0,97,96,0,0,
9,0,0,89,0,0,
10,95,99,0,0,0,
11,0,0,96,97,0,
12,0,0,0,93,98,
13,94,91,0,0,0,
14,0,83,87,0,0,
15,0,0,98,97,98,
16,0,0,0,93,86,
17,98,83,99,98,81,
18,93,87,92,96,98,
19,0,0,0,89,92,
20,0,99,96,95,81
};

请考虑此题用贪心的算法来书写试试看

注释

这道题明显是蓝桥杯第十届的组队
贪心也可以,但是你不知道自己一定对,所以推荐用DFS

思路

这里的贪心思路很明显是直接取掉最大值,但我们仍然需要注意判重,即选取一个人之后就无法再次选取这个人

注意:
这里答案虽然对了,但是这样的做法并不正确,只是在这个数据上正确而已
因为我们a[][0]优先选择最大,并且给了判重,而你无法判定这个选择是否只有当前这个位子上最大
我们也可以理解为局部最优并非全局最优?

代码
解法1.贪心版本
#include<iostream>
#include<algorithm>using namespace std;const int row = 20,col=5;
int fen[row+5][col+5];
bool st[row];//判重数组
int res;
int jIdx;//用来记录需要判重的位子,即当前选择的人是第几个人int max(int a,int b,int idx)//自定义max函数,方便判断b>a时进行操作
{if(a>b){return a;}jIdx=idx;//记录当前位子return b;
}void func()
{for(int i=0;i<col;i++)//当col过完之后,表示五个人都被选择完毕{jIdx=0;int tmp=-0x3f3f3f;for(int j=0;j<row;j++)if(!st[j])tmp = max(tmp,fen[j][i],j);//如果没选择当前这个人,更新最大值,记录这个人的位置st[jIdx]=true;//选择res+=tmp;//求和//cout<<jIdx<<" "<<i<<" "<<fen[jIdx][i]<<endl;//输出当前被选择的人员}
}int main()
{for(int i=0;i<row;i++)for(int j=0;j<col;j++)cin>>fen[i][j];func();cout<<res;//输出答案return 0;
}
答案

490

提示:

这里的货币系统非常依赖货币面额,如果不成为倍数关系等情况下就可能出现错误

1029. 两地调度【来自LeetCode里面】

公司计划面试 2N 人。第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]。
返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达。

示例:

输入:[[10,20],[30,200],[400,50],[30,20]]
输出:110
解释:
第一个人去 A 市,费用为 10。
第二个人去 A 市,费用为 30。
第三个人去 B 市,费用为 50。
第四个人去 B 市,费用为 20。

最低总费用为 10 + 30 + 50 + 20 = 110,每个城市都有一半的人在面试。

提示:
1 <= costs.length <= 100
costs.length 为偶数
1 <= costs[i][0], costs[i][1] <= 1000

思路

贪心

题目的意思就是两个城市都有一半人
要最优惠的价格

则 我们假设所有人去A,我们则肯定需要一半人去B
怎么选择着一半人,则是查找B-A正数差值最大的一半人

减去差值之后我们就相当于一半人去了A,一半人去了B,且是最优惠价格

AC截图

AC代码
解法1.贪心
class Solution {public:int twoCitySchedCost(vector<vector<int>>& costs) {int sum = 0;for(int i=0;i<costs.size();i++)sum+=costs[i][0];vector<int> arr;for(int i=0;i<costs.size();i++)arr.push_back(costs[i][0]-costs[i][1]);sort(arr.begin(), arr.end());for(int i=arr.size()-1;i>=arr.size()>>1;i--)sum-=arr[i];return sum;}
};
注明:

1.这道题没讲过
2.这道题不是作业
3.这道题没要求自学
所以应该不考

第十二周

上课题目

例1字典序最小问题

问题描述:
给定长度为N的字符串S,
要构造一个长度为N字符串T。
T开始是一个空串,反复执行下列任意操作:
1)从S的头部删除一个字符,加到T的尾部;
2)从S的尾部删除一个字符,加到T的尾部;
目标是要构造字典序尽可能小的字符串T。

颜老板思路

字典序是指从前到后比较两个字符串的大小的方法。
首先比较第1个字符,如果不同
则第1个字符较小的字符串更小,
如果相同则继续比较第2个字符…
反复继续,来比较整个字符串的大小。

思路

按照颜老板的思路我们知道是字符串前后向中间持续比较字符大小

(1)安全版
为了防止下标问题我们可以直接拆分
例如
A::ACDBCB t1
B::BCBDCA t2

给AB数组分别一个INDEX,在AB数组持续找最小,然后赋值给res数组
输出res答案即可
(2)极简版
需要注意下标处理和生成逻辑

输入 ACDBCB
输出

代码
解法1.安全版
#include<iostream>
#include<algorithm>
#include<vector>using namespace std;
vector<char>ans;int main()
{string a;cin>>a;string b=a;reverse(b.begin(),b.end());int t1,t2,t3;t1=t2=t3=0;while(1){if(a[t1]<=b[t2])ans.push_back(a[t1++]),t3++;else ans.push_back(b[t2++]),t3++;if(t3==a.size())break;}for(int i=0;i<ans.size();i++)cout<<char(ans[i]);return 0;
}
解法2.非安全,极简版

需要注意下标处理和生成逻辑

#include<iostream>using namespace std;int main()
{string a;cin>>a;int l=0,r=a.size()-1;while(l<=r)if(a[l]<a[r])cout<<a[l++];else cout<<a[r--];return 0;
}

例2背包问题:

假如我们有一个可以装100kg物品的背包,我们有5种豆子,每种豆子的总量和总价值各不相同。为了让背包中所装的物品的总价值最大,我们如何选择装哪些豆子,每种装多少?【可以选择某种物品装部分】

思路

这是一道完全背包问题

我们只需要理解,price/weight==val
如果val越高,就越优先处理即可
那么我们最终只需要一个结构体排序即可

代码
解法1.结构体排序
#include<iostream>
#include<algorithm>using namespace std;struct Node{string name;int price,weight;
};bool cmp(Node a,Node b){return a.price/a.weight>b.price/b.weight;}//自定义结构体sort降序int main()
{int sum,n;cin>>sum>>n;const int len = n;Node node[len+10];for(int i=0;i<len;i++)cin>>node[i].name>>node[i].weight>>node[i].price;sort(node,node+len,cmp);int cnt=0;while(sum){if(sum>=node[cnt].weight){cout<<node[cnt].name<<" "<<node[cnt].weight<<endl;sum-=node[cnt].weight;}//优先处理最高else{cout<<node[cnt].name<<" "<<sum<<endl;sum=0;}cnt++;}   return 0;
}

下课题目

自学题目

字符串去重

思考:任意一串字符,删除其中的重复字符!

去除字符串中重复的字符

思路

很明显从 ASCII set 哈希表 入手

代码
解法1.哈希表
#include<iostream>
#include<string>
#include<unordered_map>using namespace std;unordered_map<char,int> map;int main()
{string s;cin>>s;for(int i=0;i<s.size();i++)map[s[i]]++;for(auto x:map)cout<<x.first;return 0;
}
解法1.2哈希表 写法二
#include<iostream>
#include<string>
#include<unordered_map>using namespace std;unordered_map<char,int> map;int main()
{string s;cin>>s;for(int i=0;i<s.size();i++)map[s[i]]++;for(int i=0;i<'z';i++)if(map.count(char(i)))cout<<char(i);return 0;
}
解法2.ASCII码
#include<iostream>
#include<cstring>using namespace std;int main()
{string s;cin>>s;bool a['z'];for(int i=0;i<s.size();i++)if(!a[s[i]]){cout<<s[i];a[s[i]]=true;}return 0;
}
解法3.set
#include<iostream>
#include<set>using namespace std;int main()
{set<char>Set;string s;cin>>s;for(int i=0;i<s.size();i++)Set.insert(s[i]);for(char x:Set)cout<<x<<endl;return 0;
}

自定情况:多个字符串的情况下

思路
代码
set
#include<iostream>
#include<set>using namespace std;int main()
{set<string>Set;int n;cin>>n;for(int i=0;i<n;i++){string tmp;cin>>tmp;Set.insert(tmp);}for(string x:Set)cout<<x<<endl;return 0;
}
哈希表
#include<iostream>
#include<string>
#include<unordered_map>using namespace std;unordered_map<string,int> map;int main()
{int n;cin>>n;for(int i=0;i<n;i++){string s;cin>>s;map[s]++;}for(auto x:map)cout<<x.first;return 0;
}
ASCII

用string单个的ASCII加起来,每个位子上乘位数如(10,100)组成新的ASCII下标数据,懒得写了

霍夫曼编码 我认为不考 待补

霍夫曼编码是一种广泛用于数据文件压缩的编码方法,压缩率通常在20%到90%之间,霍夫曼编码算法根据字符出现频率,用不同的0,1串来标识字符,从而达到缩短字符串,达到压缩的目的。
还是拿课程中的算法举例:
假设有一个包含1000字符的文件,每个字符占1byte,一共需要8000bits来存储。
如果这1000个字符只包括6种字符,分别是a,b,c,d,e,f那么我们通过3个bit(最多可以标识8个字符)来表示这6个字符,那么总共需要3000bits就可以表示这个字符串了。
用这种三个bit标识一个字符,编码和解码比较简单,但是没有充分考虑每个字符在文件中出现的频率。而霍夫曼编码是结合字符在文件中的频率来进行对字符编码的,出现字符多的编码更短,由于霍夫曼编码的长短是不一样的,所以如何不让两种不同的编码之间产生混淆?那就需要保证每种编码不能为另一种编码的前缀。
假设这些字符在文件中出现的频率如下:

总bits = 1450 +2350+390+460+530+520 = 2100
2100bits比原来3000bits又压缩了近1/3, 下面问题就是如何进行霍夫曼编码了。
王争老师的算法很巧妙也简单:
1)把所有涉及到的字符按照出现频率的高低放入到优先级队列中区。
2)我们从队列中取出频率最小的两个字符上图中为f和e,然后新建个字符比如X,频率为f和e的频率之和,然后X作为f和e的父亲节点。
3)再把X节点放入到优先级队列中。
4)转到2继续指向,直到队列为空。

构造完一颗二叉树之后,我们给每条边都做个编码,比如左边的边为0,右边的为1,得到如下:

这样每个节点的编码可以用从根节点到此节点的边来表示:
1)比如a这个节点编码为1
2)c这个编码为001。

第三届蓝桥杯【省赛试题8】密码发生器

在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:
如果为了好记用生日吧,容易被破解,不安全;如果设置不好记的密码,又担心自己也会忘记;
如果写在纸上,担心纸张被别人发现或弄丢了…
这个程序的任务就是把一串拼音字母转换为6位数字(密码)。
我们可以使用任何好记的拼音串(比如名字,王喜明,就写:wangximing)作为输入,程序输出6位数字。


变换的过程如下:
第一步. 把字符串6个一组折叠起来,
比如 wangximing
则变为:
wangxi
ming
第二步. 把所有垂直在同一个位置的字符的ascii码值相加,得出6个数字,如上面的例子,
则得出:
228 202 220 206 120 105
第三步. 再把每个数字“缩位”处理:
就是把每个位的数字相加,得出的数字如果不是一位数字,就再缩位,直到变成一位数字为止。
例如: 228 => 2+2+8=12 => 1+2=3

上面的数字缩位后变为:344836, 这就是程序最终的输出结果!


要求程序从标准输入接收数据,在标准输出上输出结果。
输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行字符串,就是等待变换的字符串。

输出格式为:n行变换后的6位密码。

例如,
输入:
5
zhangfeng
wangximing
jiujingfazi
woaibeijingtiananmen
haohaoxuexi
则输出:
772243
344836
297332
716652
875843

思路

需要注意的几个点

for(i=0;i<=strlen(a)-1;i++){b[i%6]=b[i%6]+a[i];}

可以帮助字符串直接对位记录

while(x>=10){sum=0;while(x>0){sum=sum+x%10;x=x/10;}x=sum;}

取出各个位次相加,然后检查是否又>10

result[k]=f(b[0])*100000+f(b[1])*10000+f(b[2])*1000+f(b[3])*100+f(b[4])*10+f(b[5])*1;
代码
解法1.语法糖 哈夫曼距离应用
#include<iostream>
#include<cstring>using namespace std;const int len =6;int check(int x)
{int sum;while(x>=10){sum=0;while(x){sum=sum+x%10;x=x/10;}x=sum;}return x;
}int main()
{int n;cin>>n;int tmparr[len+10];for(int i=0;i<n;i++){memset(tmparr,0,sizeof tmparr);string s;cin>>s;for(int j=0;j<s.size();j++)tmparr[j%6]=tmparr[j%6]+s[j];    cout<<check(tmparr[0])*100000+check(tmparr[1])*10000+check(tmparr[2])*1000+check(tmparr[3])*100+check(tmparr[4])*10+check(tmparr[5])*1<<endl;}return 0;
}

[算法课]算法课全题目解答及各周链接相关推荐

  1. 就是这35个人,率先入选了《共识算法高阶课》第一期!

    本文的主要内容是硅谷密探<区块链共识算法(高阶)实战必修课>第一期全体 35位入围成员的完整名单. 可能有人还不熟悉<区块链共识算法(高阶)实战必修课> ,这是硅谷密探和知乎& ...

  2. 如何正确学习数据结构、算法这门课?

    你是否曾跟我一样,因为看不懂数据结构和算法,而一度怀疑是自己太笨?实际上,很多人在第一次接触这门课时,都会有这种感觉,觉得数据结构和算法很抽象,晦涩难懂,宛如天书.正是这个原因,让很多初学者对这门课望 ...

  3. Java实现 蓝桥杯 算法训练 审美课

    算法训练 审美课 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 <审美的历程>课上有n位学生,帅老师展示了m幅画,其中有些是梵高的作品,另外的都出自五岁小朋友之手.老师 ...

  4. 分治算法在排课系统中的分析与应用的改进

    论文综述: 1.解决的问题: 课表是全校教职员工和学生,为保证日常教学正常运行所必须遵守的时间进度表.要求其五大要素:班级.课程.教师.教室.时间之间的合理匹配. 2.解决方案: 课表编排问题的规模巨 ...

  5. 算法通识课发刊词:人机互动时代,懂点算法才能赢

    你好,我是吴晶辰,欢迎来到<算法通识课>. 算法对你来说,可能是购物网站上推荐的"猜你喜欢",是汽车导航规划的"最佳路线",是餐厅里的自动点菜服务. ...

  6. python 排课算法_基于遗传算法的排课系统

    摘 要:随着高校的发展,在教务管理系统中使用的排课模型也变得越来越复杂,亟需一种适用于开发.重用及设计的方法.针对这种情况,本文给出了排课问题的数学模型,提出基于遗传算法解决方案.结果表明,该算法能比 ...

  7. c语言贪心算法排课,*排课软件常用算法介绍*兴文排课*学校经常用的免费自动排课软件...

    将需要求解的课表问题逐层分解,直到得到一个最小单元的不可在分解.可以直接求出答案的子问题.分解出来的所有子问题按层次关系构成一颗子问题树.树根是课程表问题.课程表问题的解依赖于子问题树中所有子问题的解 ...

  8. 江中游A星算法 第1课 预估移动消耗计算法则

    教程:http://bbs.anjian.com/showtopic-515151-1.aspx 江中游A星算法 第1课 预估移动消耗计算法则 知识点:先明确 A星算法中的两个概念 H 和 G F H ...

  9. 秦九韶算法如何应用到计算机,《秦九韶算法》说课稿——获奖说课稿

    <<秦九韶算法>说课稿--获奖说课稿.doc>由会员分享,可免费在线阅读全文,更多与<<秦九韶算法>说课稿--获奖说课稿>相关文档资源请在帮帮文库(ww ...

  10. 目前流行的几种排课算法的介绍

    通用高校排课算法研究----2 .目前流行的几种排课算法的介绍 2   目前流行的几种排课算法的介绍 2.1. 自动排课算法 1 .问题的描述 我们讨论的自动排课问题的简化描述如下: 设要安排的课程为 ...

最新文章

  1. php基础+jquery基础
  2. java 关于日期的一些常用惯例
  3. UA SIE545 优化理论基础 例题 对偶函数的凸性与次梯度计算
  4. myeclispe快捷键一\(≧▽≦)/终于也收藏了
  5. Debian on VirtualBox下共享win7文件夹设置
  6. (延迟两秒,跳转相应页面)(返回到上一个页面并刷新)
  7. 密码与确认密码自动验证html,HTML确认密码
  8. 利用VBA把PowerDesigner的comment复制到name
  9. html页面锁屏,JavaScript网页锁屏效果源码实例
  10. mysql查询语句ppt,mysql查询表中数据总条数的语句怎么写
  11. android设备如何苹果,Android安卓设备如何连接Mac的方法
  12. Spark Streaming实现WordCount
  13. Matlab使用心得
  14. Flink 源码编译实战
  15. 解决 微信小程序 input错位
  16. mammothJs解析docx文件
  17. 小程序实现文字竖排展示
  18. shell获取系统当前时间、本月1日、下月1日、本月月底、上月月底、上月同期日期
  19. 浅谈云原生的“前世今生”
  20. 大二Web课程设计——基于HTML+CSS+JavaScript+jquery手表商城购物网站(17页)

热门文章

  1. Linux下用五笔输入法
  2. c#使用office的墨迹书写工具
  3. 姿态估计之2D人体姿态估计 - CPN(Cascaded Pyramid Network for Multi-Person Pose Estimation)
  4. 游侠更新仙剑全系列免CD补丁(支持WIN7 SP1)【转载】
  5. iOS 清理缓存简介
  6. 显示器ntsc测试软件,显示器色域检测图拉丁版
  7. Google Earth Engine(GEE)——逐日MOD10A1.005积雪覆盖度500m数据下载和均值标准差统计(中国区域为例)
  8. tw8836flash制作
  9. 兼容性良好的邮箱正则表达式
  10. 程序员的奋斗史(三十四)——人在囧途之应聘篇(四)