数据结构与算法学习笔记----求组合数

数据结构与算法学习笔记----求组合数

@@ author: 明月清了个风
@@ first publish time: 2025.1.27

ps⭐️一组求组合数的模版题,因为数据范围的不同要用不同的方法进行求解,涉及了很多之前的东西快速幂,逆元,质数,高精度等等,还有新的定理——lucas定理,卡特兰数

Acwing 885. 求组合数 I

[原题链接](885. 求组合数 I - AcWing题库)

给定 n n n组询问,每组询问给定两个整数 a a a b b b,请你输出 C a b m o d ( 1 0 9 + 7 ) C_{a}^{b} \bmod (10^9 + 7) Cabmod(109+7)的值。

输入格式

第一行包含整数 n n n

接下来 n n n行,每行包含一组 a a a b b b

输出格式

n n n行,每行输出一个询问的解。

数据范围

1 ≤ n ≤ 10000 1 \le n \le 10000 1n10000

1 ≤ b ≤ a ≤ 2000 1 \le b \le a \le 2000 1ba2000

思路

首先我需要知道组合数的基本计算方法,如有一组合数 C a b C_{a}^{b} Cab,那么其计算如下:
C a b = a ! b ! ( a − b ) ! (1) C_{a}^{b} = \frac{a!}{b!(a - b)!} \tag{1} Cab=b!(ab)!a!(1)
这里引入组合数的一个公式如下:
C a b = C a − 1 b + C a − 1 b − 1 (2) C_{a}^{b} = C_{a - 1}^{b} + C_{a - 1}^{b - 1} \tag{2} Cab=Ca1b+Ca1b1(2)
我们可以这样理解这个公式:假设我们是要在 a a a个苹果中选取 b b b个苹果,即 C a b C_{a}^{b} Cab。那么对于某一个苹果而言,只可能有两种情况——被选取和不被选取,这两种情况包含了我们要求的目标的所有方案。当这个苹果被选取了,那么这样的方案数就是 C a − 1 b − 1 C_{a - 1}^{b - 1} Ca1b1,即在剩下的 a − 1 a - 1 a1个苹果中再选取 b − 1 b - 1 b1个;当这个苹果没有被选取,其对应方案数就是 C a − 1 b C_{a - 1}^{b} Ca1b,也就是在剩下的 a − 1 a - 1 a1个苹果中仍需要选取 b b b个。

这样就意味着我们的目标是可以通过之前的组合数计算出来的,也就是可以进行递推,而不用每次都重新计算,时间复杂度也就降低了。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;const int N = 2010, mod = 1e9 + 7;int c[N][N];void init()
{for(int i = 0; i < N; i ++)for(int j = 0; j <= i; j ++)if(!j) c[i][j] = 1;else c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}int main()
{init();int n;cin >> n;while(n --){int a, b;cin >> a >> b;cout << c[a][b] << endl;}return 0;
}

Acwing 886. 求组合数 II

[原题链接](886. 求组合数 II - AcWing题库)

给定 n n n组询问,每组询问给定两个整数 a a a b b b,请你输出 C a b m o d ( 1 0 9 + 7 ) C_{a}^{b} \bmod (10^9 + 7) Cabmod(109+7)的值。

输入格式

第一行包含整数 n n n

接下来 n n n行,每行包含一组 a a a b b b

输出格式

n n n行,每行输出一个询问的解。

数据范围

1 ≤ n ≤ 10000 1 \le n \le 10000 1n10000

1 ≤ b ≤ a ≤ 1 0 5 1 \le b \le a \le 10^5 1ba105

思路

注意这题的数据范围 a , b a,b a,b都到了 1 0 5 10^5 105,如果还用上面的预处理两重循环会直接超时,这里我们直接从组合数的计算公式出发看我们要计算的是什么
C a b m o d ( 1 0 9 + 7 ) = a ! b ! ( a − b ) ! m o d ( 1 0 9 + 7 ) (1) C_{a}^{b} \bmod (10^9 + 7) = \frac{a!}{b!(a - b)!} \bmod (10^9 + 7) \tag{1} Cabmod(109+7)=b!(ab)!a!mod(109+7)(1)
这样其实就是我们熟悉的内容了,对于阶乘而言我们可以进行预处理,唯一需要注意的就是除法模运算的处理,我们可以使用之前学过的逆元将其转换为一个乘法模运算,需要做的是预处理出分母阶乘的逆元。

逆元用之前的快速幂模版即可求得,具体的看一下快速幂那一篇。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;typedef long long LL;const int N = 100010, mod = 1e9 + 7;int n;
int fact[N], infact[N];int qmi(int a, int k, int p)
{int res = 1;while(k){if(k & 1) res = (LL)res * a % p;k >>= 1;a = (LL)a * a % p;}return res;
}int main()
{cin >> n;fact[0] = infact[0] = 1;for(int i =1; i < N; i++){fact[i] = (LL)fact[i - 1] * i % mod;infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;}while(n --){int a, b;cin >> a >> b;cout << (LL)fact[a]  * infact[a - b] % mod * infact[b] % mod << endl;}return 0;}

Acwing 887. 求组合数 III

[原题链接](887. 求组合数 III - AcWing题库)

给定 n n n组询问,每组询问给定两个整数 a a a b b b p p p,其中 p p p是质数,请你输出 C a b m o d p C_{a}^{b} \bmod p Cabmodp的值。

输入格式

第一行包含整数 n n n

接下来 n n n行,每行包含一组 a a a, b b b, p p p

输出格式

n n n行,每行输出一个询问的解。

数据范围

1 ≤ n ≤ 20 1 \le n \le 20 1n20

1 ≤ b ≤ a ≤ 1 0 18 1 \le b \le a \le 10^{18} 1ba1018

1 ≤ p ≤ 1 0 5 1 \le p \le 10^5 1p105,

思路

到这一题我们可以发现 a a a b b b的数据范围变得非常大,并且模数 p p p也不再是一个固定值,因此我们引入一个新的定理——Lucas定理:
C a b ≡ C a m o d p b m o d p ⋅ C a / p b / p ( m o d p ) C_{a}^{b} \equiv C_{a \mod p}^{b \mod p} \cdot C_{a / p}^{b / p} \pmod p CabCamodpbmodpCa/pb/p(modp)
也就是我们可以将组合数分解为两个更小的组合数的乘积,并且可以递归分解,直到我们可以处理

这里的证明比较复杂,我们将y总的证明主要分为两点进行说明:

  1. 🏫 第一点是对于任意质数 p p p,有$(1 + x)^p \equiv 1 + x^p \pmod p $

    这个等式中 p p p一定要是质数,这是一个强条件,我们可以通过二项式定理进行证明,我们将 ( 1 + x ) p (1 + x)^p (1+x)p用二项式定理展开可得:
    ( 1 + x ) p = ∑ k = 0 p C p k ⋅ 1 p − k ⋅ x k = ∑ k = 0 p C p k ⋅ x k = C p 0 + C p 1 ⋅ x + C p 2 ⋅ x 2 + ⋯ + C p p ⋅ x p (1+x)^p = \sum_{k=0}^{p} C_p^k \cdot 1^{p-k} \cdot x^k = \sum_{k=0}^{p} C_p^k \cdot x^k = C_p^0 + C_p^1 \cdot x + C_p^2 \cdot x^2 + \cdots + C_p^p \cdot x^p (1+x)p=k=0pCpk1pkxk=k=0pCpkxk=Cp0+Cp1x+Cp2x2++Cppxp
    其中,$ C_p^k $ 表示从 $ p $ 个不同元素中取出 $ k $ 个元素的组合数。

    而对于任意质数 p p p,当 $ 1 \leq k \leq p-1 $ 时,有 $ p $ 能整除 $ C_p^k $。这是因为:
    C p k = p ! k ! ( p − k ) ! = p ⋅ ( p − 1 ) ⋅ ( p − 2 ) ⋯ ( p − k + 1 ) k ! C_p^k = \frac{p!}{k!(p-k)!} = \frac{p \cdot (p-1) \cdot (p-2) \cdots (p-k+1)}{k!} Cpk=k!(pk)!p!=k!p(p1)(p2)(pk+1)
    由于 p p p 是质数,且 k k k p − k p-k pk 均小于 p p p,因此 p p p 在分子中作为因子出现,而在分母中没有对应的因子可以消去,所以 p p p 能整除 C p k C_p^k Cpk

    那么由于 p p p 能整除 C p k C_p^k Cpk(当 1 ≤ k ≤ p − 1 1 \leq k \leq p-1 1kp1 时),因此在模 p p p 的意义下,这些项都等于 0:
    C p k ⋅ x k ≡ 0 ( m o d p ) ( 1 ≤ k ≤ p − 1 ) C_p^k \cdot x^k \equiv 0 \pmod p \quad (1 \leq k \leq p-1) Cpkxk0(modp)(1kp1)
    这意味着在 ( 1 + x ) p (1+x)^p (1+x)p 的展开式中,除了 C p 0 C_p^0 Cp0 C p p C_p^p Cpp 这两项外,其他所有项在模 p p p 的意义下都为 0。

    那么我们就可以将 ( 1 + x ) p (1 + x)^p (1+x)p在模 p p p的意义下进行简化:
    ( 1 + x ) p ≡ C p 0 + C p p ⋅ x p m o d p (1+x)^p \equiv C_p^0 + C_p^p \cdot x^p \mod p (1+x)pCp0+Cppxpmodp
    由于 C p 0 = 1 C_p^0 = 1 Cp0=1 C p p = 1 C_p^p = 1 Cpp=1(因为从 $ p $ 个元素中取出 $ p $ 个或 0 个元素的组合数都是 1),所以得证:

    ( 1 + x ) p ≡ 1 + x p m o d p (1+x)^p \equiv 1 + x^p \mod p (1+x)p1+xpmodp

  2. 🏫第二点就是将 a a a b b b都写为 p p p进制数
    a = a k p k + a k − 1 p k − 1 + ⋯ + a 1 p + a 0 a = a_k p^k + a_{k-1} p^{k-1} + \cdots + a_1 p + a_0 a=akpk+ak1pk1++a1p+a0

    b = b k p k + b k − 1 p k − 1 + ⋯ + b 1 p + b 0 b = b_k p^k + b_{k-1} p^{k-1} + \cdots + b_1 p + b_0 b=bkpk+bk1pk1++b1p+b0

    ( 1 + x ) a (1 + x)^a (1+x)a可以表示为 ( 1 + x ) a k p k + a k − 1 p k − 1 + ⋯ + a 1 p + a 0 (1+x)^{a_k p^k + a_{k-1} p^{k-1} + \cdots + a_1 p + a_0} (1+x)akpk+ak1pk1++a1p+a0,将指数相加变为底数相乘:
    ( 1 + x ) a k p k ⋅ ( 1 + x ) a k − 1 p k − 1 ⋅ … ⋅ ( 1 + x ) a 1 p ⋅ ( 1 + x ) a 0 (1+x)^{a_k p^k} \cdot (1+x)^{a_{k-1} p^{k-1}} \cdot \ldots \cdot (1+x)^{a_1 p} \cdot (1+x)^{a_0} (1+x)akpk(1+x)ak1pk1(1+x)a1p(1+x)a0
    这里可以将 p k p^{k} pk都先计算,即写成两层指数的形式
    ( 1 + x ) a = ( ( 1 + x ) p k ) a k ⋅ ( ( 1 + x ) p k − 1 ) a k − 1 ⋅ ⋯ ⋅ ( ( 1 + x ) p 1 ) a 1 ⋅ ( ( 1 + x ) p 0 ) a 0 (1 + x)^a = ((1+x)^{p^k})^{a_k } \cdot ((1+x)^{p^{k - 1}})^{a_{k - 1}} \cdot \cdots \cdot ((1+x)^{p^1})^{a_1} \cdot ((1+x)^{p^0})^{a_0} (1+x)a=((1+x)pk)ak((1+x)pk1)ak1((1+x)p1)a1((1+x)p0)a0
    根据上面的第一点我们可以得到
    ( 1 + x ) a ≡ ( 1 + x p k ) a k ⋅ ( 1 + x p k − 1 ) a k − 1 ⋅ ⋯ ⋅ ( 1 + x p 1 ) a 1 ⋅ ( 1 + x p 0 ) a 0 ( m o d p ) (1 + x)^a \equiv (1+x^{p^k})^{a_k } \cdot (1+x^{p^{k - 1}})^{a_{k - 1}} \cdot \cdots \cdot (1+x^{p^1})^{a_1} \cdot (1+x^{p^0})^{a_0} \pmod p (1+x)a(1+xpk)ak(1+xpk1)ak1(1+xp1)a1(1+xp0)a0(modp)
    到这里我们通过对比两遍 x b x^{b} xb的系数就可以知道 C a b ≡ C a k b k C a k − 1 b k − 1 ⋅ ⋯ ⋅ C a 1 b 1 C a 0 b 0 ( m o d p ) C_{a}^{b} \equiv C_{a_k}^{b^k}C_{a_{k - 1}}^{b^{k - 1}} \cdot \cdots \cdot C_{a_1}^{b^1}C_{a_0}^{b^0} \pmod p CabCakbkCak1bk1Ca1b1Ca0b0(modp)

这里给出一个例子吧,可能会好理解一点(应该正确吧)

假设想要计算 C ( 10 , 5 ) m o d 3 C(10, 5) \mod 3 C(10,5)mod3,其中 a = 10 a = 10 a=10 b = 5 b = 5 b=5 p = 3 p = 3 p=3
a a a b b b转换为3进制数:
1 0 10 = 10 1 3 10_{10} = 101_3 1010=1013(因为 10 = 1 ⋅ 3 2 + 0 ⋅ 3 1 + 1 ⋅ 3 0 10 = 1 \cdot 3^2 + 0 \cdot 3^1 + 1 \cdot 3^0 10=132+031+130
5 10 = 1 2 3 5_{10} = 12_3 510=123(因为 5 = 1 ⋅ 3 1 + 2 ⋅ 3 0 5 = 1 \cdot 3^1 + 2 \cdot 3^0 5=131+230
应用Lucas定理:
C ( 10 , 5 ) ≡ C ( 1 , 1 ) ⋅ C ( 0 , 2 ) ⋅ C ( 1 , 0 ) m o d 3 C(10, 5) \equiv C(1, 1) \cdot C(0, 2) \cdot C(1, 0) \mod 3 C(10,5)C(1,1)C(0,2)C(1,0)mod3
由于 C ( 0 , 2 ) = 0 C(0, 2) = 0 C(0,2)=0(因为从0个元素中选取2个元素是不可能的),所以整个表达式的结果为0。
因此, C ( 10 , 5 ) m o d 3 = 0 C(10, 5) \mod 3 = 0 C(10,5)mod3=0

代码

#include <iostream>
#include <cstring>
#include <cstring>
#include <algorithm>using namespace std;typedef long long LL;int p;int qmi(int a, int k)
{int res = 1;while(k){if(k & 1) res = (LL)res * a % p;a = (LL)a * a % p;k >>= 1;}return res;
}int C(int a, int b)
{if (b > a) return 0;int res = 1;for (int i = 1, j = a; i <= b; i ++, j -- ){res = (LL)res * j % p;res = (LL)res * qmi(i, p - 2) % p;}return res;
}int lucas(LL a, LL b)
{if(a < p && b < p) return C(a, b);return (LL)C(a % p, b % p) * lucas(a / p, b / p) % p;
}int main()
{int n;cin >> n;while(n --){LL a, b;cin >> a >> b >> p;cout << lucas(a, b) << endl;}return 0;
}

Acwing 888. 求组合数 IV

[原题链接](887. 求组合数 III - AcWing题库)

输入 a a a b b b,求 C a b C_{a}^{b} Cab的值。

注意结果可能很大,需要使用高精度计算。

输入格式

共一行,包含 a a a, b b b的值。

输出格式

共一行,输出 C a b C_{a}^{b} Cab的值

数据范围

1 ≤ b ≤ a ≤ 5000 1 \le b \le a \le 5000 1ba5000

思路

这一题的区别是没有了模数,这意味着我们的答案会非常大,因此需要使用高精度来进行计算,我们直接通过计算式进行计算即可 C a b = a ! ( a − b ) ! b ! C_{a}^{b} = \frac{a!}{(a - b)!b!} Cab=(ab)!b!a!,但是这样我们就需要进行高精度乘法以及高精度除法,因此可以进行一些优化。

优化的思路是进行质因数分解,需要统计出答案数的所有质因数的指数,这里涉及到的一个知识点就是一个数阶乘a!的某个质因子p的指数为 ⌊ a p ⌋ + ⌊ a p 2 ⌋ + ⌊ a p 3 ⌋ + ⋯ \lfloor \frac{a}{p} \rfloor + \lfloor \frac{a}{p^2} \rfloor + \lfloor \frac{a}{p^3} \rfloor + \cdots pa+p2a+p3a+

这应该挺好理解的, a ! a! a!会涉及到所有的 1 ∼ a 1 \sim a 1a中的数,那么对于包含了 p p p作为质因子的这些数而言,我们首先统计最后能够贡献一次的数的个数,即 ⌊ a p ⌋ \lfloor \frac{a}{p} \rfloor pa;但其中也会有能够贡献两次或更多次的数,也就是 p k ( k ≥ 2 ) p^k \; (k \ge 2) pk(k2)为其因子,对于这些数我们在统计一次 p 1 p^1 p1时已经统计了一次了,因此对于包含 p 2 p^2 p2为因子的数,只需再统计一次即可,即加上 ⌊ a p 2 ⌋ \lfloor \frac{a}{p^2} \rfloor p2a,以此类推。

这里的代码会涉及到之前的筛质数以及高精度乘法,可以先去看一下。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>using namespace std;const int N = 5010;int primes[N], cnt;
int sum[N];
bool st[N];void get_primes(int n)
{for(int i = 2; i <= n; i ++){if(!st[i]) primes[cnt ++] = i;for(int j = 0; primes[j] <= n / i; j ++){st[i * primes[j]] = true;if(i % primes[j] == 0) break;}}
}int get(int n, int p)
{int res = 0;while(n){res += (n / p);n /= p;}return res;
}vector<int> mul(vector<int> a, int b)
{vector<int> c;int t = 0;for(int i = 0; i < a.size(); i ++){t += a[i] * b;c.push_back(t % 10);t /= 10;}while(t) c.push_back(t % 10), t /= 10;return c;
}int main()
{int a, b;cin >> a  >> b;get_primes(a);for(int i = 0; i < cnt; i ++){int p = primes[i];sum[i] = get(a, p) - get(a - b, p) - get(b, p);}vector<int> res;res.push_back(1);for(int i = 0; i < cnt; i ++)for(int j = 0; j < sum[i]; j ++)res = mul(res, primes[i]);for(int i = res.size() - 1; i >= 0; i --) cout << res[i];puts("");return 0;
}

Acwing 889. 满足条件的01序列

[原题链接](889. 满足条件的01序列 - AcWing题库)

给定 n n n 0 0 0 n n n 1 1 1,它们将按照某种顺序排成长度为 2 n 2n 2n的序列,求他们能排列成的所有序列中,能构满足任意前缀序列中 0 0 0的个数都不少于 1 1 1的个数的序列有多少个。

输出的答案对 1 0 9 + 7 10^9+7 109+7取模

输入格式

共一行,包含整数 n n n

输出格式

共一行,包含一个整数,表示答案。

数据范围

1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105

思路

这一题其实是卡特兰数的一种数学模型,这里就先直接给出他的计算公式了(百度学了一下,应该不止这一种公式,这里就写y总讲的了)
h ( n ) = C 2 n n − C 2 n n − 1 = C 2 n n n + 1 h(n) = C_{2n}^{n} - C_{2n}^{n - 1} = \frac{C_{2n}^{n}}{n + 1} h(n)=C2nnC2nn1=n+1C2nn
我们这里也用y总讲的模型进行讲解——可以将其看为一个路径计数的问题

我们将选 0 0 0看做向左走一步,选 1 1 1看做向上走一步,假设我们一共需要走12步,那么我们一半一半选的终点就是 ( 6 , 6 ) (6,6) (6,6),并且所有的路径方案数为 C 2 n n = C 12 6 C_{2n}^{n} = C_{12}^{6} C2nn=C126下图中给出了一条符合题意的路径,大家可以看一下,到达终点前的所有前缀路径中向左走的步数都不小于向上走的步数,图中红线为对称线
在这里插入图片描述

要找出的是所有符合这种条件的路径,因此可以反向思考,也就是找到所有不符合条件的路径,在下图中给出了一条不符合题意的橙色路径,图中紫色斜线为另一条关键线,可以看到,当橙色路径第一次碰到紫色斜线时,表明其破坏了题目所要求的条件,我们也由此可以看出若一条路径会碰到或者穿过紫色斜线,其为不符合题意的路径,我们要做的就是找出所有这样的路径。
在这里插入图片描述

这里的做法比较巧妙,我们将橙色路径第一次碰到紫色斜线的部分后面进行轴对称,如下图绿色路径所示,所有经过紫色斜线的路径经过这样操作之后,其终点一定为点 ( 5 , 7 ) (5,7) (5,7),因为在轴对称之前的终点固定是 ( 6 , 6 ) (6,6) (6,6)

那么就可以得出这样的结论:所有从 ( 0 , 0 ) (0,0) (0,0)出发到达点 ( 5 , 7 ) (5,7) (5,7)的路径都可以由不满足题意的到达 ( 6 , 6 ) (6,6) (6,6)的路径经过上述变换得到,其数量为 C 2 n n − 1 = C 12 5 C_{2n}^{n - 1} = C_{12}^{5} C2nn1=C125

因此最后要求的路径数目就是 C 12 6 − C 12 5 C_{12}^{6} - C_{12}^{5} C126C125
在这里插入图片描述

最后实现到代码上我们肯定要进一步化简,也就是 h ( n ) = C 2 n n − C 2 n n − 1 = C 2 n n n + 1 h(n) = C_{2n}^{n} - C_{2n}^{n - 1} = \frac{C_{2n}^{n}}{n + 1} h(n)=C2nnC2nn1=n+1C2nn

看题目给出的数据范围是 1 0 5 10^5 105,因此需要使用的是上面组合数第二题的计算方法。

代码

#include <iostream>
#include <algorithm>using namespace std;typedef long long LL;const int N = 100010, mod = 1e9 + 7;int qmi(int a, int k, int p)
{int res = 1;while (k){if (k & 1) res = (LL)res * a % p;a = (LL)a * a % p;k >>= 1;}return res;
}int main()
{int n;cin >> n;int a = n * 2, b = n;int res = 1;for (int i = a; i > a - b; i -- ) res = (LL)res * i % mod;for (int i = 1; i <= b; i ++ ) res = (LL)res * qmi(i, mod - 2, mod) % mod;res = (LL)res * qmi(n + 1, mod - 2, mod) % mod;cout << res << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8462.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kaggle社区LLM Classification Finetuning

之前有个一样的比赛&#xff0c;没去参加&#xff0c;现在弄了一个无限期的比赛出来 训练代码链接&#xff1a;fine_tune | Kaggle 推理代码链接&#xff1a;https://www.kaggle.com/code/linheshen/inference-llama-3-8b?scriptVersionId219332972 包链接&#xff1a;pack…

【Python实现机器遗忘算法】复现2021年顶会 AAAI算法Amnesiac Unlearning

【Python实现机器遗忘算法】复现2021年顶会 AAAI算法Amnesiac Unlearning 1 算法原理 论文&#xff1a;Graves, L., Nagisetty, V., & Ganesh, V. (2021). Amnesiac machine learning. In Proceedings of the AAAI Conference on Artificial Intelligence, volume 35, 115…

51单片机开发:点阵屏显示数字

实验目标&#xff1a;在8x8的点阵屏上显示数字0。 点阵屏的原理图如下图所示&#xff0c;点阵屏的列接在P0端口&#xff0c;行接在74HC595扩展的DP端口上。 扩展口的使用详见&#xff1a;51单片机开发&#xff1a;IO扩展(串转并)实验-CSDN博客 要让点阵屏显示数字&#xff0…

买卖股票的最佳时机 II

hello 大家好&#xff01;今天开写一个新章节&#xff0c;每一天一道算法题。让我们一起来学习算法思维吧&#xff01; 问题分析 本题要求计算在可以多次买卖股票&#xff08;但任何时候最多只能持有一股股票&#xff0c;也可以在同一天买卖&#xff09;的情况下能获得的最大…

2024年度总结——理想的风,吹进现实

2024年悄然过去&#xff0c;留下了太多美好的回忆&#xff0c;不得不感慨一声时间过得真快啊&#xff01;旧年风雪尽&#xff0c;新岁星河明。写下这篇博客&#xff0c;记录我独一无二的2024年。这一年&#xff0c;理想的风终于吹进现实&#xff01; 如果用一句话总结这一年&am…

LosslessScaling-学习版[steam价值30元的游戏无损放大/补帧工具]

LosslessScaling 链接&#xff1a;https://pan.xunlei.com/s/VOHc-yZBgwBOoqtdZAv114ZTA1?pwdxiih# 解压后运行"A-绿化-解压后运行我.cmd"

CVE-2020-0796永恒之蓝2.0(漏洞复现)

目录 前言 产生原因 影响范围 漏洞复现 复现环境 复现步骤 防御措施 总结 前言 在网络安全的战场上&#xff0c;漏洞一直是攻防双方关注的焦点。CVE-2020-0796&#xff0c;这个被称为 “永恒之蓝 2.0” 的漏洞&#xff0c;一度引起了广泛的关注与担忧。它究竟是怎样的…

计算机网络 (61)移动IP

前言 移动IP&#xff08;Mobile IP&#xff09;是由Internet工程任务小组&#xff08;Internet Engineering Task Force&#xff0c;IETF&#xff09;提出的一个协议&#xff0c;旨在解决移动设备在不同网络间切换时的通信问题&#xff0c;确保移动设备可以在离开原有网络或子网…

node 爬虫开发内存处理 zp_stoken 作为案例分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言 主要说3种我们补环境过后如果用…

基于Python的哔哩哔哩综合热门数据分析系统的设计与实现

【Django】基于大数据的哔哩哔哩综合热门数据分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统涵盖登录、热门数据展示、数据分析及数据管理等功能。通过大数据处理与…

Object类(2)

大家好&#xff0c;今天我们继续来看看Object类中一些成员方法&#xff0c;这些方法在实际中有很大的用处&#xff0c;话不多说&#xff0c;来看。 注&#xff1a;所有类都默认继承Object类的&#xff0c;所以可调用Object类中的方法&#xff0c;如equals&#xff0c;也可以发生…

C++封装红黑树实现mymap和myset和模拟实现详解

文章目录 map和set的封装map和set的底层 map和set的模拟实现insertiterator实现的思路operatoroperator- -operator[ ] map和set的封装 介绍map和set的底层实现 map和set的底层 一份模版实例化出key的rb_tree和pair<k,v>的rb_tree rb_tree的Key和Value不是我们之前传统意…

单片机基础模块学习——PCF8591芯片

一、A/D、D/A模块 A——Analog 模拟信号:连续变化的信号(很多传感器原始输出的信号都为此类信号)D——Digital 数字信号:只有高电平和低电平两种变化(单片机芯片、微控制芯片所能处理的都是数字信号) 下面是模拟信号和连续信号的区别 为什么需要进行模拟信号和数字信号之…

Blazor-Blazor Web App项目结构

让我们还是从创建项目开始&#xff0c;来一起了解下Blazor Web App的项目情况 创建项目 呈现方式 这里我们可以看到需要选择项目的呈现方式&#xff0c;有以上四种呈现方式 ● WebAssembly ● Server ● Auto(Server and WebAssembly) ● None 纯静态界面静态SSR呈现方式 WebAs…

自动驾驶中的多传感器时间同步

目录 前言 1.多传感器时间特点 2.统一时钟源 2.1 时钟源 2.2 PPSGPRMC 2.3 PTP 2.4 全域架构时间同步方案 3.时间戳误差 3.1 硬件同步 3.2 软件同步 3.2.3 其他方式 ① ROS 中的 message_filters 包 ② 双端队列 std::deque 参考&#xff1a; 前言 对多传感器数据…

神经网络|(一)加权平均法,感知机和神经元

【1】引言 从这篇文章开始&#xff0c;将记述对神经网络知识的探索。相关文章都是学习过程中的感悟和理解&#xff0c;如有雷同或者南辕北辙的表述&#xff0c;请大家多多包涵。 【2】加权平均法 在数学课本和数理统计课本中&#xff0c;我们总会遇到求一组数据平均值的做法…

算法题(48):反转链表

审题&#xff1a; 需要我们将链表反转并返回头结点地址 思路&#xff1a; 一般在面试中&#xff0c;涉及链表的题会主要考察链表的指向改变&#xff0c;所以一般不会允许我们改变节点val值。 这里是单向链表&#xff0c;如果要把指向反过来则需要同时知道前中后三个节点&#x…

DroneXtract:一款针对无人机的网络安全数字取证工具

关于DroneXtract DroneXtract是一款使用 Golang 开发的适用于DJI无人机的综合数字取证套件&#xff0c;该工具可用于分析无人机传感器值和遥测数据、可视化无人机飞行地图、审计威胁活动以及提取多种文件格式中的相关数据。 功能介绍 DroneXtract 具有四个用于无人机取证和审…

SpringBoot中Excel表的导入、导出功能的实现

文章目录 一、easyExcel简介二、Excel表的导出2.1 添加 Maven 依赖2.2 创建导出数据的实体类4. 编写导出接口5. 前端代码6. 实现效果 三、excel表的导出1. Excel表导入的整体流程1.1 配置文件存储路径 2. 前端实现2.1 文件上传组件 2.2 文件上传逻辑3. 后端实现3.1 文件上传接口…

C语言,无法正常释放char*的空间

问题描述 #include <stdio.h> #include <stdio.h>const int STRSIZR 10;int main() {char *str (char *)malloc(STRSIZR*sizeof(char));str "string";printf("%s\n", str);free(str); } 乍一看&#xff0c;这块代码没有什么问题。直接书写…