auto:
stoi/stod
头文件:<string>
upper_bound、lower_bound
是一个用二分法在已排序好的数组里查找元素。
头文件:#include<algorithm>
upper_bound(n):查找第一个大于n的元素,返回地址。
lower_bound(n):查找第一个大于等于n的元素,返回地址。
助记:(up主是独一无二的,所以upper没有等于,lower有等于)
使用方法:
①直接作为数组的方法调用
set<int> a;
if(a.upper_bound(2)!=a.end()){...} //查找是否存在大于2的元素
②将数组作为参数
int num[6]={1,2,4,7,15,34};
sort(num,num+6); //按从小到大排序
int pos1=lower_bound(num,num+6,7)-num; //返回数组中第一个大于或等于被查数的值
cout<<pos1<<" "<<num[pos1]<<endl; //输出 3 7
③查找小于或小于等于
int num[6]={1,2,4,7,15,34};
sort(num,num+6,cmd); //按从大到小排序
int pos3=lower_bound(num,num+6,7,greater<int>())-num; //返回数组中第一个小于或等于被查数的值
cout<<pos3<<" "<<num[pos3]<<endl; //输出 4 7
printf输出位数不够补零
int x = 7;
printf("%03d", x); //补0凑齐3位,输出 007
int转string,前缀自动补零
string tostring(int x) {
string s = to_string(x);
while (s.size() < 5) ///补5位
s = "0" + s;
return s;
}
关于运行超时
在创建容器的时候,可以尽量作为全局变量,有时候可能作为局部变量有些用例超时。
关于遍历vector、map等容器
vector<int>a(n);
for(auto i:a)
cout<<i<<endl;
vector可以作为map的键值
map<vector<int>, int>mp;
重写sort中cmp方法
bool cmp(type a, type b) {
return a > b; //">"是大顶堆,"<"是小顶堆
}
getline()
接收一个字符串,包括空格,头文件<string>
string s;
getline(cin,s);
关于取整的写法
(x+2)/3 等同于 [x/3] (对x/3取整)。
fill()
头文件:<algotithm>,原型:fill(first,last,val)
#include<algotithm> //fill头文件
#include<vector>
int a[10];
vector<int>aa(n);
int aaa[4][5];
fill(a,a+6,6); //将a[0]~a[5]赋值为6
fill(aa.begin(),aa.begin()+4,8) //将aa[0]~aa[3]赋值为8
fill(aaa,aaa+4*5,10) //二维数组赋值
memset()
头文件:<cstring>
填充字符,一般用来填充char数组,对于int数组只能改为(0,-1,INF),没有 1
memset()与fill()区别
memset速度比fill()更快
fill可以赋任何值;而memset就0,-1,INF,-INF
无穷大与无穷小
int a = 0x7fffffff; //输出:2147483647
int b = (1 << 31)-1; //输出:2147483647
int c = 0x3f3f3f3f; //输出:1061109567
int d = 1 << 30; //输出:1073741824
int e = 1 << 31; //输出:-2147483648
int f = 0xc0c0c0c0; //输出:-1061109568
vector二维数组表示
vector<int >a[n]; //二维数组大小为a[n][],列的大小未初始化
//可以用a[i].push_back(x)插入值
判断素数
bool isPrime(int x){
for(int i=2;i<sqrt(x);i++)
if(x%i==0)
return false;
return true;
}
find()
可以创建一个数组,不限制大小,出现的元素就push_back,用find()查找
适用于vector ,map ,set , string
值得一提的是,map,set,string是用其本身的find()方法,而vector本身没有find(),他是用<algorithm>库中find()函数
vector<int>a;
if(find(a.begin(),a.end(),y)!=a.end())
//do something
map<int,int>mp;
if(mp.find(1)!=mp.end())
//do something
set<int>st;
if(st.find(1)!=st.end())
//do something
string s;
if(s.find('a')!=string::npos) //注意是 string::npos
//do something
printf打印 “%”
printf中用 %% 来打印%,只有一个%打不出来
double a = 3.11;
printf("%.1lf%%",a); //输出:3.1%
使用引用访问容器中的元素
vector<int> a{1,6,7,9,0,4,5};
for(int i:a)
i+=1; //错误
for(int& i:a)
i+=1; //正确
unordered_map、unordered_set、map、set
头文件:前者 <unordered_map><unordered_set>,后者<map><set>
unordered_map,unordered_set与map,set之间最主要区别就是前者无序存放,后者根据键值有序存放,也就是当使用迭代器遍历打印map,set时,后者会按键值从小到大打印,前者键值无序打印。
使用时机:当只是为了存储,查找元素,保证元素互异,用ordered_map、ordered_set会更好
排序功能
尽量使用sort()进行排序,不要依赖map、set的自动排序,结构庞大
binary_search()
头文件:<algorithm>
对有序数组进行二分查找,返回bool
同余定理
如果a%n=b%n,就可以说a与b同余,则(a-b)%n=0。也就是说a-b是n的整数倍。
了解到这个定理是因为今天做了一题(如下),一开始暴力将每一种组合都枚举,但是会超时。百度了一下才发现可以用这个定理进行一定的剪枝。
也就是计算每个数对n的余数,如果这个余数出现过了,就不把这个数加进去,达到剪枝的效果。
min_element, max_element
max_element(first,end,cmp)
min_element(first,end,cmp)
返回容器中的最大(小)值的地址,取值记得加 *,还可以自定义cmp函数
判断素数
#include<cmath>
bool isPrime(int x){
for(int i=2;i<=sqrt(x);i++)
if(x%i==0) return false;
return true;
}
ps:循环条件是小于等于sqrt(x),头文件加个<cmath>,0,1不是素数
自定义优先队列
struct cmp(){ //重写仿函数
bool operator() (typdef a,typdef b){
return a>b;
}
};
priority_queue<typedf,vector<typedf>,cmp>q;
ps:和sort的cmp不一样,sort直接 bool cmp(tydef a, typdef b) { return a>b; }
最后一行的cmp没有括号
next_permutation()和prev_permutation()
头文件:<algorithm>
用来计算容器中的全排列
next_permutation从小到大(字典序),prev_permutations从大到小,“最佳拍档”那篇wblg有用到
关于max()
头文件:<algorithm>
max()函数只能接收两个参数,当要进行多个参数取最值时应包含多个max()
#include<algorithm>
int a=0;
a = max(max(2,5), max(3,6));
当输入一组0结束
例如:4 5 6
7 5 8
0 0 0
int a,b,c;
while(cin>>a>>b>>c && c!=0)
关于long long
"
%lld
“和”%llu
"是**linux下gcc/g++**用于long long int类型(64 bits)输入输出的格式符。"
%I64d
“和”%I64u
"是**Microsoft VC++**库里用于输入输出__int64类型的格式说明。
for
for(obj var : collection_to_loop)
char转string
char c = 'a';
string s;
s = string(1, c); //用到string构造函数
最大公约数
//if+while+位运算,a b可为0
int gcd(int a,int b){
if(b) while((a%=b)&&(b%=a))
return a+b;
}
最小公倍数
法1:利用 a * b = a与b的最大公约数 * a与b的最小公倍数。
最小公倍数 = a * b / 最大公约数
法2:将较大的数扩大n倍(n=1,2,3…… 且 n<=最小的数)记为num,当num能整除较小数,此时num即为最小公倍数。代码如下:
if(n<m){ //让n为较大数
int t=n;
n=m;
m=t;
}
for(int i=1;i<=m;i++){
if((i*n)%m==0)
break;
}
cout<<"最小公倍数为"<< i*n <<endl;
输出四舍五入保留整数
int a,b,x;
x=a*1.0/b*100+0.5;
//加上0.5实现四舍五入