算法笔记
时间复杂度
O(log2n) | O(n) | O(nlog2n) | O(n^2) | O(2^n) | O(n!) | |
---|---|---|---|---|---|---|
n<12 | √ | √ | √ | √ | √ | √ |
n<26 | √ | √ | √ | √ | √ | × |
n<=5e3 | √ | √ | √ | √ | × | × |
n<=1e6 | √ | √ | √ | × | × | × |
n<=1e7 | √ | √ | × | × | × | × |
n<=1e8 | √ | × | × | × | × | × |
C++与STL
判断EOF
while(cin>>a){
}
一些细节
cin的速度比scanf慢了不少
输出小数用printf方便一点
动态开辟内存
打比赛不用
引用
可以把引用当成一个不能改变指向对象的指针
函数的重载
方法名一样,参数不一样
结构体
struct 类型名{
数据类型1 成员变量1;
数据类型2 成员变量2,成员变量2,成员变量2;
}[结构体变量名];
struct 已经定义过的类型名 结构体变量名;
c语言标准库
cstring
strlen()字符串长度
strcmp()字符串比较
strcpy()字符串拷贝
memset()暴力清空
memset(str,0,sizeof(str))
memcpy()暴力拷贝
cmath
cstdlib
qsort()快排
rand()随机数
ctime
clock()程序启动到目前位置的毫秒数
ccytpe
isdigit(),isalpha()判断是否为数字,大小写字母
c++标准库
vector
vector数组,一个超级数组
vector<类型> 数组名
还可以看作一个链表,可以动态的变长
list.size();//数组元素个数
list.clear();//一键清空数组
list.empty();//数组是否为空
list.begin();//数组的首字符迭代器
list.end();//数组最后一个元素的下一个元素的迭代器
list.erase(p1);//删除数组的某个迭代器所在位置的数字
list.push_back(1);//往数组后面添加元素
list.pop_back();//删除数组最后一个元素
迭代器
vector<int>::iterator p1;
for(p1=arr1.begin();p1!=arr1.end();p1++)
{
cout<<*p1<<endl;
}
string
可以看成一个特殊的vector
string和c语言字符串的关系就和vector和普通数组的关系语言
string str = "hello";
str.length(); str.size();
str.insert(1,"aaa")//在下标为1的地方插入一个字符或者字符串
str.insert(str.begin(),'a');//在迭代器处插入一个字符或字符串
str.c_str();//返回c语言字符串
str.append(str2);//把str2拼接到str后面
str.compare(str2);//strcmp(str,str2)
str == str2;//strcmp(str,str2) == 0
str += str2;//str.append(str2)
str += 'a';//str.push_back('a')
algorithm
arr[] = {2,3,1,5,4}
sort(arr,arr+5);//快排
min(1,2);
max(1,2);
nth_element(arr.begin(),arr.begin()+n,arr.end);//第二个参数是保证第几个元素处于正确排序位置
swap(arr[0],arr[1]);//交换
reverse(arr.begin(),arr.end());//反转数组
int newLength = unique(arr.begin(),arr.end()) - arr.begin();
unique(arr.begin(),arr.end());//去除已经排序好的数组的重复元素
bool isExist = binary_search(arr.begin(),arr.end(),1);//查找对应元素是否存在
lower_bound(arr.begin(),arr.end(),2);//插入一个数到有序数组,返回它第一个插入位置的指针
uper_bound();//插入一个数到有序数组,返回它最后个插入位置的指针
stack
栈,先进后出
queue
队列,先进先出
set,multiset
set集合,自带去重
multiset多重集合 可以有重复
map
映射
map<string,int> student;//前面是下标,后面为值
bitset
位集合
functional
complex
unordered_map,unordered_set
bits/stdc++.h万能头文件
memset(c,0,sizeof©);清空数组c
四舍五入
(int)(a*10+0.5)/10.0
万能库
#include<bits/stdc++.h>
__gcd()求最大公约数
#include
sort()函数,排序
产生一个a,b的随机数
srand(time(0
))
rand()%(b-a+1)+a
cin会在空格后隔断
此时可以使用fgets(s,sizeof(s),stdin);
算法与数据结构
排序与二分
快排
分治思想
1.确定分界点(随机)
2.调整区间
3.递归处理两边
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
作者:yxc
链接:https://www.acwing.com/blog/content/277/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
归并排序
1.确定分界点(mid=(l+r)/2)
2.递归排序
3.归并 合二为一
void merge_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid);
merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else tmp[k ++ ] = q[j ++ ];
while (i <= mid) tmp[k ++ ] = q[i ++ ];
while (j <= r) tmp[k ++ ] = q[j ++ ];
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
作者:yxc
链接:https://www.acwing.com/blog/content/277/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二分
有单调性的一定可以二分,可以二分的题目不一定要单调
核心思想:
字符串
string s//定义
s+=str或s.append(str)//在后面评价字符串str
s<str//比较字符串s的字典序是否在字符串str的字典序之前
s.size()或s.length()//得到字符串s的长度
s.substr(pos,len)//截取字符串s,从第pos个位置开始len个字符,并返回这个字符串
s.insert(pos,str)//在字符串pos位置前插入字符串str,并返回这个字符串
s.find(str,[pos])//在政府和s中从第pos个位置开始寻找str,并返回位置,如果找不到返回-1.pos可以省略默认为0
文件操作和重定向
freopen(“文件名”,r,stdin);
freopen(“文件名”,w,stdout);
属于cstdio头文件