1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
并查集教程
int n, m;
int sum= 0 ;
int num= 0 ;
struct edge {
int u, v, w;
} a[ MAX] ;
int findRoot ( int t) {
if ( fa[ t] != t)
fa[ t] = findRoot ( fa[ t] ) ;
return fa[ t] ;
}
bool cmp ( edge a, edge b) {
return a. w< b. w;
}
int Kruskal ( ) {
int fa[ MAX] ;
for ( int i= 1 ; i<= n; i++ ) {
fa[ i] = i;
}
sort ( a+ 1 , a+ m+ 1 , cmp) ;
for ( int i= 1 ; i<= m; i++ ) {
if ( findRoot ( a[ i] . u) != findRoot ( a[ i] . v) ) {
fa[ findRoot ( a[ i] . u) ] = findRoot ( a[ i] . v) ] ;
ans+= a[ i] . w;
num++ ;
}
if ( num== n- 1 ) {
cout<< ans<< '\n' ;
return 0 ;
}
}
cout<< "error" << '\n' ;
return 0 ;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
2.3.2 前缀和差分
声明一下,前缀和、差分是两个算法 一维、二维的前缀和、差分教学视频
2.3.3 二分法
二分法教程
2.4 中频算法
2.4.1 动态规划
之所以将动态规划划分到这里,是不想让你们死扣动态规划,动态规划考察的方法千变万化,很不容易掌握, 可能你学了之后,考试考到了一个别的,你还是不会,按照学习的性价比来说,动态规划的性价比没有前面的高。 动态规划有:线性DP,区间DP,背包问题,树形DP,数位DP,前三种相对于后两种来说,算是容易的,后两种比较难,考试基本不考,考到了也需要很熟练才能拿分,故在此处不展开叙述。
2.4.1.1 线性DP
数字三角形
dp[ 1 ] [ 1 ] = a[ 1 ] [ 1 ] ;
for ( int i= 2 ; i<= n; i++ ) {
for ( int j= 1 ; j<= i; j++ ) {
dp[ i] [ j] = max ( dp[ i- 1 ] [ j- 1 ] , dp[ i- 1 ] [ j] ) + a[ i] [ j] ;
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
最大连续子段和
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
最长公共子序列
for ( int i= 0 ; i<= len1; i++ ) dp[ i] [ 0 ] = 0 ;
for ( int j= 0 ; j<= len2; j++ ) dp[ 0 ] [ j] = 0 ;
for ( int i= 1 ; i<= len1; i++ ) {
for ( int j= 1 ; j<= len2; j++ ) {
if ( s1[ i- 1 ] == s2[ j- 1 ] ) {
dp[ i] [ j] = dp[ i- 1 ] [ j- 1 ] + 1 ;
} else {
dp[ i] [ j] = max ( dp[ i- 1 ] [ j] , dp[ i] [ j- 1 ] ) ;
}
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
最长上升子序列
for ( int i= 1 ; i<= n; i++ ) {
dp[ i] = 1 ;
for ( int j= 1 ; j< i; j++ ) {
if ( a[ j] < a[ i] ) {
dp[ i] = max ( dp[ i] , dp[ j] + 1 ) ;
}
}
if ( dp[ i] > MaxNum) {
MaxNum= dp[ i] ;
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
2.4.1.2 区间DP
游艇租赁
for ( int d= 3 ; d<= n; d++ ) {
for ( int i= 1 ; i<= n- d+ 1 ; i++ ) {
int j= i+ d- 1 ;
for ( int k= i+ 1 ; k< j; k++ ) {
if ( dp[ i] [ j] > dp[ i] [ k] + dp[ k] [ j] ) {
dp[ i] [ j] = dp[ i] [ k] + dp[ k] [ j] ;
}
}
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
回文问题 定义:dp[i][j]表示将字符串s的子区间[i][j]转化为回文串的最小成本 转移:if(s[i]==s[j]), dp[i][j]=dp[i+1][j-1] if(s[i]!=s[j]),dp[i][j]=min(dp[i+1][j]+min(arr[i][0],arr[i][1]),dp[i][j-1]+min(arr[j][0],arr[j][1])) 初始化:dp[i][j]=0; 目标: dp[0][m-1]
括号匹配问题 定义:dp[i][j]表示字符串i到j区间的最长正则括号子序列的长度 转移:括号匹配分两种情况 情况①嵌套((())) 转移:if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2; else dp[i][j]=max(dp[i+1][j],dp[i][j-1]); 情况②拼接 ()()() 转移:if(s[i]==s[j]) dp[i][j]=max(dp[i][k]+dp[k+1][j]); (k=i,i+1,…,j-1) else dp[i][j]=max(dp[i+1][j],dp[i][j-1]); 初始化dp[i][j]=0 目标:dp[0][len-1]
2.4.1.3 背包问题
0-1背包问题 :每个物品只有一个,只有放和不放两种可能 定义:dp[j]表示容量为j的背包放入前i种物品时的最大容量 转移:if(w[i]<=j) dp[j]=max(dp[j],dp[j-w[i]]+v[i]);(倒推,因为需要用到上一行的旧数据) 初始化:dp[j]=0; 目标: dp[m] 完全背包 :物品有无限多个,可以放入的数量不可估量 定义:dp[j]表示容量为j的背包放入前i种物品时的最大容量 转移:if(w[i]<=j) dp[j]=max(dp[j],dp[j-w[i]]+v[i]);(正推,因为需要用到当前行的新数据) 初始化:dp[j]=0; 目标: dp[m] 多重背包:每个物品的数量有限
for ( int i= 1 ; i<= n; i++ )
for ( int k= 1 ; k<= c[ i] ; k++ )
for ( int j= m; j>= w[ i] ; j-- )
dp[ j] = max ( dp[ j] , dp[ j- w[ i] ] + v[ i] ) ;
for ( int i= 1 ; i<= n; i++ ) {
if ( d[ i] * w[ i] >= m) {
for ( int j= w[ i] ; j<= m; j++ ) {
dp[ j] = max ( dp[ j] , dp[ j- w[ i] ] + v[ i] ) ;
}
} else {
for ( int k= 1 ; c[ i] > 0 ; k<<= 1 ) {
int x= min ( c[ i] , k) ;
c[ i] -= x;
for ( int j= m; j>= w[ i] * x; j-- ) {
dp[ j] = max ( dp[ j] , dp[ j- w[ i] * x] + x* v[ i] ) ;
}
}
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
分组背包
for ( int i= 1 ; i<= n; i++ )
for ( int j= m; j>= 0 ; j-- )
for ( int k= 1 ; k<= c[ i] ; k++ )
if ( j> w[ i] [ k] )
dp[ j] = max ( dp[ j- w[ i] [ k] ] + v[ i] [ k] , dp[ j] ) ;
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
混合背包
for ( int i= 1 ; i<= n; i++ ) {
if (
ZeroOnePack ( c[ i] , w[ i] ) ;
} else if (
CompletePack ( c[ i] , w[ i] )
} else if (
MultiplePack ( c[ i] , w[ i] , n[ i] )
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
3 辅助算法
这里的算法是不会单独考察的,而是穿插在其它算法里的一小步,掌握好辅助算法,可以帮助你快速做题。
3.1 排序
3.1.1 优先队列
struct Node {
int num;
int mosst;
} ;
struct cmpl {
bool operator ( ) ( Node d1, Node d2) {
if ( d1. num== d2. num) {
return d1. mosst> d2. mosst;
} else {
return d1. num> d2. num;
}
}
} ;
priority_queue< Node, vector< Node> , cmpl> q;
Node temp;
q. push ( temp) ;
q. top ( ) ;
q. pop ( ) ;
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
3.1.2 sort排序
①int数组
# include
# include
using namespace std;
int main ( ) {
int arr[ ] = { 5 , 2 , 9 , 1 , 5 , 6 } ;
int n = sizeof ( arr) / sizeof ( arr[ 0 ] ) ;
sort ( begin ( arr) , end ( arr) ) ;
for ( int i = 0 ; i < n; ++ i)
cout << arr[ i] << " " ;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
②vector类型
# include
# include
# include
using namespace std;
int main ( ) {
vector< int > vec = { 3 , 1 , 4 , 1 , 5 , 9 } ;
sort ( vec. begin ( ) , vec. end ( ) ) ;
for ( auto & v : vec)
cout << v << " " ;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
③自定义类型
# include
# include
# include
# include
using namespace std;
struct Person {
string name;
int age;
Person ( string n, int a) : name ( n) , age ( a) { }
} ;
bool compare_by_age ( const Person & a, const Person & b) {
return a. age < b. age;
}
int main ( ) {
vector< Person> people = {
Person ( "Alice" , 30 ) ,
Person ( "Bob" , 25 ) ,
Person ( "Charlie" , 35 )
} ;
sort ( people. begin ( ) , people. end ( ) , compare_by_age) ;
for ( const auto & person : people)
cout << person. name << " " << person. age << "\n" ;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
3.2 string 字符串使用
string s = "Hello World" ;
cout << "Size: " << s. size ( ) << "\n" ;
if ( s. empty ( ) ) {
cout << "String is empty\n" ;
}
string sub = s. substr ( 0 , 5 ) ;
size_t pos = s. find ( "World" ) ;
if ( pos != string:: npos) {
cout << "Found at position: " << pos << "\n" ;
}
s. insert ( 5 , ", " ) ;
string s1 = "Hello" ;
string s2 = "hello" ;
if ( s1. compare ( s2) == 0 ) {
std:: cout << "Strings are equal\n" ;
} else {
std:: cout << "Strings are not equal\n" ;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
4 练习网站推荐
4.1 边学边练
4.1.1蓝桥杯题库
①蓝桥杯 C/C++ 组历届真题合集 在这里你可以通过标签筛选练习题,来巩固你刚学过的算法
②蓝桥成套真题演练 在这里面,你可以找到成套真题,适合用作考前模拟题,考试时间为4小时,平时学习时,可能边查资料边写代码,导致做题速度较慢,这到考场是致命的伤,一定要提前模拟!! 遗憾的是,这个题目是真实比赛时的试卷,不能判断你写的对错,如果要知道对错,你需要复制题目,到蓝桥杯 C/C++ 组历届真题合集 这里面搜索对应的题目,再将题解复制过去,查看对错。
4.1.2 leetcode题库
leetcode题库 在这里,你可以筛选题目难度,题目标签 每道题都有题解,可以选择题解的语言类别,查看大佬们的思路,从而充实自己的大脑,终有一天,你也可以发布题解,得到多人的点赞
4.2 小试牛刀
4.2.1 蓝桥算法双周赛等
一些同学,可能觉得平常自己练习没有时间上的紧迫感,这里推荐一些小比赛,可以自己参加试试。 蓝桥竞赛 这里面是蓝桥杯官方的一些比赛
4.2.2 leetcode竞赛
leetcode竞赛
4.2.3牛客竞赛
牛客竞赛 ,可以挑选赛制
4.3 其它
其实以上网站就足够你练习题目了,下面推荐的网站是几个也能练题的网站,学有余力可以做,但是如果你放弃上面三个做题网站,而选择下面几个,就是舍本逐末了。 洛谷 码蹄集 C语言网 包含了很多题目集,也包括蓝桥杯的。 有些人喜欢在C语言网做蓝桥的题,可以参考这篇博文C语言网在ACM蓝桥杯等算法竞赛的妙用 Virtual Judge 支持多个国际知名的在线编程竞赛平台,包含了北京大学,PTA,洛谷等,剩下很多需要翻墙才能访问,我也没用过,感兴趣可以自己研究。
5 赛前须知
第16届蓝桥杯报名官网 每一届报名网址都不一样,比如第15届的报名网址就不是这个,所以如果未来想找第17届,第18届的,自己百度搜索第某某届蓝桥杯报名官网就行。 报名官网上可以看到大赛的最新消息,要学会自己查大赛的规则。 蓝桥别—>关于大赛—>比赛大纲 点开比赛大纲,第十六届蓝桥杯大赛软件赛和电子赛竞赛大纲 ,下载压缩包,查看大赛规则。
5.1 比赛要求(考前必看)
竞赛时长: 4小时(一般是上午9点到下午1点) 机器配置: X86兼容机器,内存不小于4G,硬盘不小于60G。 操作系统:Windows7、Windows8、Windows10或Windows11 编程环境: Dev-cpp 5.11(支持C++11标准) C/C++ API 帮助文档
(建议大家平时练习时也使用这个环境,防止比赛时因为不熟悉而浪费时间)
5.2 Dev配置(考前必会)
一般学校机考,会给你下载好Dev和API帮助文档,但是全都是默认配置,需要你自己配置成自己习惯的使用方式。
5.2.1 设置为中文界面
http://iyenn.com/rec/1641036.html
5.2.2 使用C++11新标准
Dev5.11默认是不开启C++11标准的,可以选择开启
http://iyenn.com/rec/1641037.html 这里记住自己使用的Dev是哪个标准的: 如果配置了C++11标准,代码运行正常,那么提交时也选择C++11。 如果没有配置C++11标准,且代码运行正常,那么提交时选择C++即可。
5.2.3 Dev-C++环境下的degug使用
实话实说:其实Dev-C++5.11的调试功能,有严重的Debug。 经常在单步调试时,遇到卡住无法向下一步执行的问题。如果遇到了该问题,建议不要死磕,可以使用打印语句来模拟debug 。 (我找过很多解决方案,有的建议把endl换成"\n",但是调试时还是会卡住,相信我这个前人的话,不要死磕) Dev-C++环境调试如何使用?
5.2.4 万能头文件
Dev中默认自带这个头文件,所以直接使用即可,无需配置
# include
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
5.3 考试答疑
5.3.1 提交时如何选择编译环境?
官方提醒!!! 如何知道自己平时练习时使用的环境呢? 平时蓝桥官网提交的C++(g++17)都是支持c++11的。由于蓝桥杯是OI赛制,即提交后不反馈分数,如果因为编译器选择错误,导致丢分,将非常可惜。为了万无一失,建议使用自己的Dev环境模拟比赛环境(上面5.2.2已经介绍) 。
5.3.2 考试时可以上厕所吗?
可以的。征得监考老师同意就可以去 ,毕竟考试时长4小时,不可能不让你上厕所。
5.3.3 可以带纸和笔吗?
可以的,可以带上纸和笔 。有的学校是自己发放草稿纸,这时只需带笔就行。
5.3.4 用谁的电脑?
一般是使用机房电脑,学校统一组织监考。 请注意:如果学校机房的电脑比较破旧,答题文件请保存在除了C盘以外的盘符 ,并实时保存。 (因为学校电脑破旧,所以可能会卡顿,蓝屏,这时就需要重启电脑,而我们学校的电脑是重启会自动清空C盘,只留操作系统,如果你的题目保留在C盘,那么恭喜你前功尽弃,重新开始答题)
评论记录:
回复评论: