蓝桥杯算法常用模板整合(c++)
数学计算类
最大公约数gcd
__gcd(a, b)
最小公倍数lcm
(a * b) / __gcd(a, b)
整数快速幂
int pow(int a,int b){
//ans:幂的结果 base:底数
int ans = 1,base = a;
while(b) {
if(b&1){
ans=base*ans;
}
base=base*base;
b=b>>1;
}
return ans;
}
质数筛
const int prime_N = 1000009;
int prime[prime_N], prime_cnt;// 质数数组,质数个数。
bool prime_st[prime_N];// prime_st[i]=true表示 i 不是质数
void get_prime(int prime_n)//表示筛质数的范围在1~prime_n
{
for(int i = 2;i <= prime_n;++ i) {
if (!prime_st[i]) prime[prime_cnt ++] = i;
for(int j = 0;prime[j] <= prime_n / i;++ j) {
prime_st[prime[j] * i] = true;
if (i % prime[j] == 0) break;
}
}
}
逆元求组合数
int fac[N];
int power(int x, int k, int p) {
int ret = 1;
while(k) {
if(k & 1) ret = ret * x % p;
k >>= 1;
x = x * x % p;
}
return ret % p;
}
int inv(int x, int p) { //求x关于模p的逆元
return power(x, p - 2, p) % MOD;
}
int C(int a, int b) { //直接用逆元求解组合数C(a, b)
return fac[a] * inv(fac[b], MOD) % MOD * inv(fac[a - b], MOD) % MOD;
}
void solve()
{
//预处理
fac[0] = 1;
for(int i = 1; i <= n; i++) fac[i] = fac[i - 1] * i % MOD;
//求C i k (i在下,k在上)
cout << C(i, k) << endl;
}
十进制转为2~36进制:
itoa (i, s, 16);
// i:十进制int, s:char[ ],16:转换进制
sprintf (s, "%x", i);
// s:char[ ],”%x“16进制,”%8o“八进制宽度8,i为int
字符串(2~36进制)转十进制
atoi (s)
数据结构
并查集
(1)朴素
int p[N]; //存储每个点的祖宗节点
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ ) p[i] = i;
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
(2)维护size
int p[N], size[N];
//p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
size[i] = 1;
}
// 合并a和b所在的两个集合:
size[find(b)] += size[find(a)];
p[find(a)] = find(b);
(3)维护到祖宗节点距离
int p[N], d[N];
//p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x)
{
int u = find(p[x]);
d[x] += d[p[x]];
p[x] = u;
}
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
d[i] = 0;
}
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量
DP
01背包
二维
int m,n;//m为总背包大小,n为物品个数
cin>>m>>n;
int weight[n],value[n];
for(int i=0;i<n;i++){
cin>>weight[i]>>value[i];
}
int dp[n][m+1]={0};
//初始化
for(int i=weight[0];i<=m;i++){
dp[0][i]=weight[0];
}
for(int i=1;i<n;i++){//遍历物品
for(int j=0;j<m+1;j++){//遍历背包容量
if(j<weight[i]){
dp[i][j]=dp[i-1][j];
}else{
dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
}
}
}
cout<<dp[n-1][m]<<endl;
一维优化
int m,n;//m为总背包大小,n为物品个数
cin>>m>>n;
int weight[n],value[n];
for(int i=0;i<n;i++){
cin>>weight[i]>>value[i];
}
int dp[m+1]={0};
for(int i=0;i<n;i++){//遍历物品
for(int j=m;j>=weight[i];j--){
dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
}
}
cout<<dp[m]<<endl;
完全背包 物品无限
int m,n;
cin>>m>>n;
int weight[n],value[n];
for(int i=0;i<n;i++){
cin>>weight[i]>>value[i];
}
int dp[m+1]={0};
for(int i=0;i<n;i++){
for(int j=weight[i];j<=m;j++){
dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
}
}
cout<<dp[m]<<endl;