刷题知识总结

基础知识

头文件

  • #include <bits/stdc++.h> //几乎包含所有头文件

输入输出

  • fgets (buf, MAX, stdin):获取一行字符串,可以获取空格

二分

  • 头文件algorithm
    lower_bound(address_start,address_end,value): 返回的是value出现的第一个位置。
    lower_bound(address_start,address_end,value): 返回的是大于value的值出现的第一个位置。
    binary_search(address_start,address_end,value):返回的是是否存在这么一个数,是一个bool值。

排序

  • 头文件algorithm
    sort(address_start,address_end,cmp):sort默认是升序排序,bool型变量cmp可以改变排序方式

数学问题

最大公约数与最小公倍数

  • gcd最大公约数的求解:
int gcd(int a,int b){
	if(b==0) return a;
	else return gcd(b,a%b);
}
  • 最小公倍数:a*b/gcd(a,b);

分数的表示与运算

  • 分数的表示和化简
struct Fraction{    //分数的表示
	long long up,down;    //up是分子,down是分母
};    
Fraction reduction(Fraction result){    //分数的化简
	if(result.down<0){    //分母小于0,分子分母均取负
		result.down=-result.down;
		result.up=-result.up;
	}
	if(result.up == 0){    //分子为0,分母取任意非0常数,取1
		result.down=1;
	}else{    //求分子分母的绝对值的最大公约数,化简
		int d=gcd(abs(result.down),abs(result.up));
		result.down /= d;
		result.up /= d;
	}
	return result;
}
  • 分数的四则运算
    按照分数的四则运算公式,计算出分子与分母,最后化简
  • 分数的输出
 void showResult(Fraction r){
 	r=reduction(r);    //化简
 	if(r.down == 1) printf("%lld",r.up);    //分母为1,该分数为整数
 	else if(abs(r.up)>r.down){    //假分数,以带分数形式输出
 		printf("%d  %d/%d",r.up/r.down,abs(r.up)%r.down,r.down);
 	}else{    //真分数时,直接输出 
 		printf("%d/%d",r.up,r.down);
 	}
 }

素数

  • 素数的判断
bool IsPrime(int n){
	if(n<=1) return false;
	for(int i=2;i<=(int)sqrt(n*1.0);i++){
		if(n%i == 0) return false;
	}
	return true;
}
  • 素数表的获取
const int maxn = 1000    //表长
int prime[maxn],pNum = 0;    //prime数组存放所有素数,pNum为素数个数
bool p[maxn] = {false};    //p[i] == true表示i是素数
void Find_Prime(){
	for(int i=1;i<maxn;i++){
		if(IsPrime(i)==true){
			prime[pNum++]=i;    //是素数则把i存入prime数组
			p[i]=true;
		}
	}
}
  • 质因子
struct factor{
	int value;    //质因子的值
	int count;    //质因子个数
}
Find_Prime();    //获取素数表
int num;    //不同素数的个数
for(int i=0;i<pNum && prime[i]<=(int)sqrt(n*1.0);i++){    //判断从1到根号n的质因子是否是n的质因子
	if(n%prime[i] == 0){    //prime[i]是n的质因子
		fac[num].value=prime[i];    //记录该质因子
		fac[num].count=0;    //该质因子个数记为0
	}
	while(n%prime[i] == 0){    //统计该质因子个数
		fac[num].count++;
		n /= prime[i];
	}
	if(n != 1){    //若无法被根号n内的质因子除尽
		fac[num].value=n;   //仅有一个质因子,为n
		fac[num++].count=1;
	}
}

大整数运算

  • 大整数的存储
const int maxn=1000;
struct bign{    //bign是字符串形式存储
	int d[maxn];    //存储大整数的各位数
	int len;    //大整数的长度
	bign(){    //构造函数初始化
		memset(d,0,sizeof(d));
		len=0;
	}
};	

二叉树

二叉树的存储

  • 链式存储:二叉链表
struct Node{
	typename data;
	Node* lchild;
	Node* rchild;
};
  • 顺序存储(完全二叉树)
    存储在数组中,

图论

图的存储

  • 邻接矩阵:用二维数组表示G[N][N]
  • 邻接表:
    只存储每条边的终点编号:vector<int> Adj[N],添加从 i 到 j 边时,只需要Adj[i].push_back(j)语句即可
    要存放其他信息时,用结构体:
struct Node{
	int v;   //边的终点编号
	int w;   //边权
	Node(int _v,int _w) : v(_v),w(_w) {}    //构造函数
	ElemType info;    //其他信息
};
vector<Node> Adj[N];    //邻接表
/*若不定义构造函数,则利用中间变量实现加边操作
Node temp;
temp.v = 3;
temp.w = 4;
Adj[1].push_back(temp);
*/
Adj[i].push_back(Node(3,4));   //利用构造函数做加边操作

图的遍历

  • DFS:将经过的结点设置为已访问,下次递归碰到该结点时就跳过,直到访问完所有节点为止。
const int MAXV 200;
const int INF 1e9;
//邻接矩阵版本
int n,G[MAXV][MAXV];  //n为总顶点数
bool vis[MAXV] = {false};    //标识一个结点是否被访问,初值为false
void DFS(int u,int depth){    //u为当前访问的结点的编号,depth为深度
	vis[u] = true;    //u已被访问
	for(int v = 0; v<n; v++){    //检查u的邻接点,递归遍历
		if(G[u][v]!=INF && vis[v] = false){
			DFS(v,depth+1);
		}
	}
}
void DFSTrave(){    //遍历图
	for(int u=0;u<n;u++){    //查询每个结点u
		if(vis[u] == false){    //u未被访问,则访问u
			DFS(u,1);
		}
	}
}
//邻接表版本
const int MAXV 200;
const int INF 1e9;
//邻接矩阵版本
int n;  //n为总顶点数
vector<int> Adj[MAXV]
bool vis[MAXV] = {false};    //标识一个结点是否被访问,初值为false
void DFS(int u,int depth){    //u为当前访问的结点的编号,depth为深度
	vis[u] = true;    //u已被访问
	for(int i = 0; i<Adj[u].size(); i++){    //检查u的邻接点,递归遍历
		int v = Adj[u][i];   //取u的邻接点
		if(vis[v] = false){
			DFS(v,depth+1);
		}
	}
}
void DFSTrave(){    //遍历图
	for(int u=0;u<n;u++){    //查询每个结点u
		if(vis[u] == false){    //u未被访问,则访问u
			DFS(u,1);
		}
	}
}
  • BFS
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值