刷题知识点总结(C++)

总结

  • int型的范围
  • 输入为多组测试数据
  • string型变量使用printf输出
  • STL中string函数transform实现大小写转换
  • 稳定排序stable_sort()
  • STL中string容器str.find()
  • map容器find()
  • map有clear()函数但是queue没有
  • 使用cin来输入一行中间有空格的字符串
  • 左对齐五个宽度输入
  • memset初始化只能对0和-1使用
  • 搜索问题
    • DFS模板
    • BFS模板
  • 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 > 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)来读入

你可能感兴趣的:(刷题,模板,其他心得总结)