总结
- int型的范围
- 输入为多组测试数据
- string型变量使用printf输出
- STL中string函数transform实现大小写转换
- 稳定排序stable_sort()
- STL中string容器str.find()
- map容器find()
- map有clear()函数但是queue没有
- 使用cin来输入一行中间有空格的字符串
- 左对齐五个宽度输入
- memset初始化只能对0和-1使用
- 搜索问题
- string中寻找子串、替换字串
- string字符串判断是否被访问过
- 部分背包问题通式
- 区间贪心
- 哈夫曼树
- 将char字符变成int
- 向下取整和向上取整
- 当使用二维数组超时的时候,可以使用二维map
- lower_bound( )和upper_bound( )
- set:: iterator tp;
- 遇到有关图的题时,邻接表还是邻接矩阵
- 二维数组或者vector可以单独对第二维进行sort排序
- 当RE的时候,不妨再扩大一下maxn的值
- 当只用dfs一次,只需要得到一个方案时
- 加快for循环速度
- exit(0)
- 不要题中n给多大,maxn就设置多大
- 记忆化搜索
- fill初始化二维数组(非-1/0)
- 当遇到输入为“-100 blabla bla” 【两个char[]】
int型的范围
int的取值范围为: -231——231-1,即-2147483648——2147483647,如果题目中输入的整数不超过1,000,000,000都可以使用int型变量。
输入为多组测试数据
当题目中要求,输入为多组测试数据,每行一组时,使用:
int main(){
int a,b;
while(scanf("%d %d",&a,&b) != EOF){
······
}
return 0;
}
string型变量使用printf输出
需要加上str.c_str()
int main(){
string s = "asgf";
printf("%s",s.c_str());
}
STL中string函数transform实现大小写转换
使用::toupper
转大写,使用tolower
转小写
int main(){
string s = "asgf";
transform(s.begin(),s.end(),s.begin(),::toupper);//转大写
printf("%s",s.c_str());
}
稳定排序stable_sort()
当遇到相同数据都按先录入排列在前的规则处理时,排序不能使用sort(),只能使用stable_sort()。
STL中string容器str.find()
如果查找不到子串会返回string::npos。
map容器find()
map.find(key)可以查找map中的键key对应的映射的迭代器。
map有clear()函数但是queue没有
queue通过不断循环来pop()
while(!Q.empty()) Q.pop();
使用cin来输入一行中间有空格的字符串
string s;
while(getline(cin,s)){
}
使用getline(cin,s)来输入一行中间还有空格的字符串
不然cin>>s 会以空格隔开输入
左对齐五个宽度输入
%-5d
-
——左对齐
memset初始化只能对0和-1使用
memset(G,-1/0,sizeof(G);
搜索问题
如果求方案数,使用dfs,不能用bfs。
如果求步数,可以使用bfs。
DFS模板
int dfs(int t)
{
if(满足输出条件)
{
输出解;
}
else
{
for(int i=1;i<=尝试方法数;i++)
if(满足进一步搜索条件)
{
为进一步搜索所需要的状态打上标记;
search(t+1);
恢复到打标记前的状态;//也就是说的{回溯一步}
}
}
}
BFS模板
void BFS(int start){
queue<int> q;
q.push(start);
while(!q.empty()){
访问队首元素top;[q.front()]
弹出队首元素q.pop();
将top的下一层结点 未曾入队 的结点全部入队;
将这些结点设置为已入队;
}
}
string中寻找子串、替换字串
str.find(substr)!=string::npos
此时可以在str中找到substr子串
str.replace(pos,len,str2)
把str从pos号位开始,长度为len的子串替换为str2.
string字符串判断是否被访问过
使用set< string > vis;
如果vis.count(str) == 0
则说明没有出现过str子串,否则就是重复的,之后再把str放入set:vis.insert(str)
因为set集合中元素不会重复
部分背包问题通式
注意这类问题的通式:
先声明一个结构体来存重量,价值和单位价值。
读入数据后,计算每类物品的单位价值,然后按单位价值从高到低排序
之后循环所有物品,每次选择单价最高的物品,如果重量<=背包:将该物品所有全部装入;如果重量>背包,将单价*背包容量的装入。
区间贪心
排序cmp规则:
比较左端点坐标不同,则大的在前;相同,则按右端点小的在前
bool cmp(contest x, contest y){
if(x.a != y.a) return x.a>y.a;
else return x.b < y.b;//左端点相同按右端点从小到大排序
}
哈夫曼树
使用优先队列来存放结点,因为优先队列可以保持时刻队列中都是有序的。
//设置优先级队列,值越小优先级越高
priority_queue<int,vector<int>,greater<int> > q;//存放果子
将char字符变成int
string s;
int a[];
a[i] = s[i]-'0';
向下取整和向上取整
floor(double x); ——向下取整
ceil(double x); ——向上取整
使用floor函数。floor(x)返回的是小于或等于x的最大整数。
如:
floor(10.5) == 10 floor(-10.5) == -11
使用ceil函数。ceil(x)返回的是大于x的最小整数。
如:
ceil(10.5) == 11 ceil(-10.5) ==-10
当使用二维数组超时的时候,可以使用二维map
map<key1,map<key2,value> > mmap;
lower_bound( )和upper_bound( )
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
set:: iterator tp;
*tp可以取tp迭代器所指的值
遇到有关图的题时,邻接表还是邻接矩阵
当题目中提到顶点的个数为105 数量级时,此时使用邻接矩阵(G[maxn][maxn])存图明显会超时,所以应该用邻接表存图(vector< node > adj[maxn])
二维数组或者vector可以单独对第二维进行sort排序
for(int i=1;i<=n;i++){
sort(adj[i].begin(),adj[i].end());
}
当RE的时候,不妨再扩大一下maxn的值
当只用dfs一次,只需要得到一个方案时
使用一个flag标志位,在递归边界里将flag置为true,同时在dfs函数开头要加上判断flag的语句,这样才不会导致回溯时把原方案覆盖。
void dfs(int last,int step){
if(flag==1) return;//找到了最短方案立即返回
if(step == n){
flag=1;
for(int i =1;i<=sum;i++){
ans[i] = now[i];
}
return;
}
········
}
加快for循环速度
把后面的i++,变为++i,此时对循环并没有影响,同时加快了速度
exit(0)
可以在子函数中使用exit(0);
来使调用子函数时,结束时直接退出,而不是再次执行下面的主函数程序。
不要题中n给多大,maxn就设置多大
这样有时候会出现RE或者TLE
当n<105,不妨设置maxn=1000010
记忆化搜索
记忆化搜索,用来减少搜索次数,防止超时
每次搜索记录下来已经已经搜索过的点的值,下次搜到这个点,直接用已经求过的值即可。
用s数组存放记忆
int dfs(int x,int y){
if(s[x][y]) return s[x][y];//记忆化搜索
for(int i=0;i<4;i++){
·····
}
fill初始化二维数组(非-1/0)
fill(dp[0],dp[0]+maxn*maxn,INF);
当遇到输入为“-100 blabla bla” 【两个char[]】
在使用scanf("%s",a)
读取第一个字符串的时候,要先使用getchar()
吸收空格,然后再使用gets(b)
读取第二个带空格的字符串
当带空格的字符串无法使用gets时,可以使用cin.getline(str,length)
来读入