c++算法初解—卷(1)

本文详细介绍了蓝桥杯算法比赛中的编程基础知识,包括C++语言的版本选择、输入输出、string的使用,以及竞赛中常用的库函数如排序、查找、STL容器和基础算法。涵盖了时间复杂度、数据结构等关键概念。
摘要由CSDN通过智能技术生成

蓝桥杯算法笔记(一)



1 语言基础

1.1 编程基础

1.1.1 C++基础格式与版本选择

01.C++版本区别与选择
C++98:第一个版本。
C++03:值的初始化引入其中。
C++11(蓝桥杯选用):引入了Lambda表达式、委托构造函数、统一初始化语法、自动类型推导auto、decltype、Rvalue等。
C++14:添加了多态Lambda、数字分隔符、通用Lambda捕获、变量模板、二进制整数文字、引用字符串等。
C++17:引入了折叠表达式、十六进制浮点文字、u8字符文字、带有初始化程序的选择语句、内联变量等。
02.C++代码格式与语法基础

#include <bits/stdc++.h> //万能头文件
using namespace std;

int main(){ //main函数是C++内置的启动函数
	cout<<"hello,world!"<<endl; //cout是输出流,更细节的是cout是输出到屏幕。endl是换行符
	printf("hello,world!");
	return 0; //函数遇到return结束,返回0
}

输出结果:
hello,world!
hello,world!

#include <bits/stdc++.h>
using namespace std;
int main(){
	int x=2;
	double c=3.14;
	char z='a';
	char s[]="hello";
	bool b=true; //布尔值,即真假值
	cout<<x<<'\n';
	cout<<c<<'\n';
	...
	return 0;
}

输出整型、浮点型、字符、字符串、布尔型等。
03.手撕代码
数组:

#include <bits/stdc++.h>
using namespace std;
//const表示变量,后续不可被修改
const int N=1e5+9;
int a[N];
int main(){
	...
	return 0;
}

typedef:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll
const int N=1e5+9;
ll a[N];
int main(){
	...
	return 0;
}

字符串:

#include <bits/stdc++.h>
using namespace std;
int main(){
	char s[]="hello";
	for(int i=0;i<5;++i){
		cout<<s[i];
	}
	cout<<'\n';
	cout<<s<<'\n';
	return 0;
}

输出偶数:

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n=10;
	for(int i=1;i<=n;++i){
		if(i%2==0)cout<<i<<'\n';
	}
	return 0;
}

1.1.2 输入输出

01.scanf和printf
例1:

int main(){
	double a,b; //声明
	scanf("%lf %lf",&a,&b);
	printf("%.2lf,%.3lf",a,b);
	return 0;
	}

例2:%s输入遇到空格或者回车就会停下

int main(){
	char s[10];
	scanf("%s",s); //此时的s代表的是s这个字符串的首地址
	printf("%s",s);
	return 0;
	}
scanf("[^\n]",s); //[]是一个正则表达式,表示只要不是回车就都进去。

02.cin 和 cout
如下:

int mian(){
	int a,b;
	cin>>a>>b; //自动判断变量类型
	cout<<a<<' '<<b<<'\n';
	return 0;
	}
int main(){
	double a,b;
	cin>>a>>b;
	cout<<fixed<<setprecision(3)<<a<<' '<<b<<'\n'; //setprecision()设置保留小数点后三位。
	return 0;
	}

cin 输入字符串的时候也是遇到空格或者回车就结束。使用getline()函数可以输入空格

int main(){
	string s;
	getline(cin,s);
	cout<<s;
	return 0;
	}

03.取消同步流
由于 cin 和 cout 需要自动判断变量类型等内部原因,读写效率比scanf和printf更低。
当数据量较大时,可能导致程序运行超时。
我们可以取消同步流来加速cin和cout.

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); //取消同步流
	int x;cin>>x;
	cout<<x<<'\n';
	return 0;
	}

代码示例:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N=150;
int a[N];
int main(){
	//取消同步流
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;cin>>n;
	for(int i=1;i<=n;++i)cout<<a[i]; //遍历
	for(int i=n;i>=1;--I)cout<<a[i]; //逆遍历
	return 0;
	}

字符串输入输出:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N=150;
char s[N];
int main(){
	//取消同步流
	ios_sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>s+1; //从s[1]的位置开始输入
	for(int i=1;s[i];++i)cout<<s[i]; //s[i]如果等于 '\0',结束循环
	return 0;}

1.1.3 string的使用

01.string简介
string是C++标准库的重要组成部分,主要用于字符串处理,string库包含在头文件#include中。(包含万能头文件#include <bits/stdc++.h>可以不写string头文件)
string和cahr[]不同,string实现了高度封装,可以很方便的完成各种字符串操作,比如拼接、截取、匹配等等。
string的特性:

  1. 字符串管理:string封装了字符串的存储和管理。它可以自动处理字符串的内存分配和释放,避免了手动管理内存的麻烦。
  2. 动态大小调整:string可以根据需要自动调整字符串的大小。在添加或删除字符时,string会自动调整内部的存储容量,确保足够的空间来容纳字符串。
  3. 安全性:string提供了一些方法来确保字符串的安全性。例如,它提供了越界访问检查,以避免访问超出字符串范围的字符。
  4. 迭代器支持:string支持迭代器,可以使用迭代器遍历字符串中的字符,进行字符级别的操作。
  5. 兼容性:string是C++标准库的一部分,因此在C++中广泛使用,并且与其他标准库组件和C++语言特性兼容。
    02.string的声明和初始化
#include <iostream>
#include <string>
//using namespace std;
int main(){
	//声明并初始化一个空字符串
	std::string str1;
	//使用字符串自变量初始化字符串
	std::string str2 = "hello,world!";
	//使用另一个std::string 对象来初始化字符串
	std::string str3 = str2;
	//使用部分字符串初始化字符串,substr()子串截取函数
	std::string str4 = str2.substr(0,5);
	//使用字符数组初始化字符串
	const char* charArray = "hello";
	std::string str5(charArray);
	//使用重复的字符初始化字符串
	std::string str6(5,'A');
	//输出字符串内容
	std::cout<<"str1:"<<str1<<std::endl; //空
	std::cout<<"str2:"<<str2<<std::endl; //hello,world!
	std::cout<<"str3:"<<str3<<std::endl; //hello,world!
	std::cout<<"str4:"<<str4<<std::endl; //hello
	std::cout<<"str5:"<<str5<<std::endl; //hello
	std::cout<<"str6:"<<str6<<std::endl; //AAAAA
	}

03.各种基本操作

  1. 在C++中,std::string类提供了一个成员函数c_str(),用于返回一个指向以空字符结尾的C风格字符串(即const char*类型)。在进行printf输出时,需要将string转换为C风格的字符串进行输出。
#include <bits/stdc++.h>
using nmaespace std;
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	char buf[100]; //存放零时变量,用于输出
	scanf("%s",buf); //输入buff
	string str(buf); //使用buff来构造str
	printf("str = %s\n",str.c_str()); //输出str
	}
  1. 获取字符串长度(length/size)
string str = "hello,world";
int length = str.length(); // 或者int length = str.size();
cout<<"length:"<<length<<endl;
  1. 字符串查找(find)
string str = "hello,world";
size_t pos = str.find("world"); //查找子字符串的位置
if(pos != string::npos){
	cout<<"Substring found at position:"<<pos<<endl;
	}else{
	cout<<"Substring not found"<<endl;
	}
  1. 拼接字符串(+ 或者 append)
string str = "hello";
string str1 = "world";
string result1 = str +", "str1; //使用 + 号拼接
string result2 = str.append(", ").append(str1); //使用append()函数拼接
  1. 字符串替换(replace)
string str1 = "hello,world!";
str1.replace(7,5,"Universe"); //替换字符串,7 起始位置,5 字符长度
cout<<"result:"<<str1<<endl; //hello,Universe!
  1. 提取子字符串(substr)
string str1 = "hello,world!";
string subStr = str1.substr(7,5); //提取字符串,7 起始位置。5 提取个数,注意:不要越界
cout<<"Substring:"<<subStr<<endl;

  1. 字符串比较(compare)
    string重载了不等号,所以可以直接用s1<s2的方式来比较string的大小,比较的规则是按照字典序大小进行比较。
    字典序的比较方法是从小到大一个一个比较,一旦遇到不相等的字符就确定大小关系。
string str1 = "hello";
string str2 = "world";
int result = str1.compare(str2); //比较字符串
if(result == 0){
	cout<<"String are equal."<<endl;
}else if(result < 0){
	cout<<"String 1 is less than String 2"<<endl;
}else{
	cout<<"String 1 is greater than String 2"<<endl;
}
  1. 遍历
    常用的遍历方法有两种:
    1)循环枚举下标
    2)auto枚举(其中&表示取引用类型,如果对i 修改将会改变原来的值)
string s = "hello";

for (int i = 0;i<s.length();++i)cout<<s[i];
cout<<'\n';

for(auto i : s){
	cout<<i;
	i = 'a'; //此处修改无效,因为这里的i是拷贝出来的,而不是引用s里面的。
	}
cout<<'\n';
//此时s = hello;
for(auto &i : s){
	cout<<i;
	i ='a'; //此处修改s的值
}
cout<<'\n';
//此时s = aaaaa;
cout<<s<<'\n';

04.例题
实现字符数组的反转功能

#include <bits/stdc++.h>
using namespace std;

int main(){
string s;
getline(cin,s);
for(int i=(int)s.length()-1;i>=0;--i){
	cout<<s[i];}
return 0;
} //将字符逆序输出,原字符不变

int main(){
string s;
getline(cin,s);
reverse(s.begin(),s.end());
cout<<s<<'\n';
return 0;
} //使用迭代器

int main(){
string s;
getline(cin,s);
for(int i=0;i<s.length()/2;++i)swap(s[i],s[s.length()-i-1]);
cout<<s<<'\n';
return 0;
} //利用下标置换

1.2 竞赛常用库函数

1.2.1 排序

1.2.2 最值查找

1.2.3 二分查找

1.2.4 大小写转换

1.2.5 全排列

1.2.6 其他库函数

1.3 STL

1.3.1 pair

1.3.2 vector

1.3.3 list

1.3.4 stack

1.3.5 queue

1.3.6 set

1.3.7 map

1.3.8 总结

2 基础算法

2.1 基础算法

2.1.1 时间复杂度

2.1.2 枚举

2.1.3 模拟

2.1.4 递归

2.1.5 进制转换

2.1.6 前缀和

2.1.7 差分

2.1.8 离散化

2.1.9 贪心

2.1.10 双指针

2.1.11 二分

2.1.12 倍增

2.1.13 构造

2.1.14 位运算

2.2 排序

2.2.1 冒泡排序

2.2.2 选择排序

2.2.3 插入排序

2.2.4 快速排序

2.2.5 归并排序

2.2.6 桶排序

3 搜索

3.1 DFS基础&回溯

3.2 DFS-剪枝

3.3 记忆化搜索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值