【马蹄集】—— 概率论专题:第二类斯特林数
概率论专题:第二类斯特林数
目录
- MT2224 矩阵乘法
- MT2231 越狱
- MT2232 找朋友
- MT2233 盒子与球
- MT2234 点餐
MT2224 矩阵乘法
难度:黄金 时间限制:5秒 占用内存:128M
题目描述
输入两个矩阵,第一个矩阵尺寸为 l × m l×m l×m ,第二个矩阵尺寸为 m × n m×n m×n ,请你输出这两个矩阵相乘后的结果矩阵。
格式
输入格式:第一行输入三个整数 l , m l,m l,m 和 n n n;
接下来 l l l 行,每行 m m m 个整数,表示第一个矩阵;
再接下来 m m m 行,每行 n n n 个整数,表示第二个矩阵。
输出格式:输出 l l l 行,每行 n n n 个整数,表示结果矩阵。样例 1
输入:
4 3 4
1 2 3
4 -5 6
7 8 9
-3 2 1
4 5 6 7
8 6 9 7
0 0 1 0输出:
20 17 27 21
-24 -10 -15 -7
92 83 123 105
4 -3 1 -7备注
其中: 1 ≤ l , m , n ≤ 1000 1≤l,m,n≤1000 1≤l,m,n≤1000, − 1000 ≤ 矩阵中的元素 ≤ 1000 -1000≤矩阵中的元素≤1000 −1000≤矩阵中的元素≤1000。
相关知识点:
线性代数
题解
求解本题只需要知道矩阵乘法的规则即可。设 A A A 为 m × p m×p m×p 的矩阵, B B B 为 p × n p×n p×n 的矩阵,那么矩阵 A A A 与 B B B 可进行乘法运算。设 C = A B C=AB C=AB,则矩阵 C C C 为一个 m × n m×n m×n 的矩阵,且 C C C 的第 i i i 行第 j j j 列元素可被表示为:
C i j = ∑ k = 1 p a i k b k j = a i 1 b 1 j + a i 2 b 2 j + … + a i p b p j C_{ij}=\sum_{k=1}^{p}{a_{ik}b_{kj}}=a_{i1}b_{1j}+a_{i2}b_{2j}+\ldots+a_{ip}b_{pj} Cij=k=1∑paikbkj=ai1b1j+ai2b2j+…+aipbpj
如对 A 2 × 3 = [ a 11 a 12 a 13 a 21 a 22 a 23 ] A_{2\times3}=\left[\begin{matrix}a_{11}&a_{12}&a_{13}\\a_{21}&a_{22}&a_{23}\\\end{matrix}\right] A2×3=[a11a21a12a22a13a23]、 B 3 × 2 = [ b 11 b 12 b 21 b 22 b 31 b 32 ] B_{3\times2}=\left[\begin{matrix}b_{11}&b_{12}\\b_{21}&b_{22}\\b_{31}&b_{32}\\\end{matrix}\right] B3×2= b11b21b31b12b22b32 ,则有:
C 2 × 2 = A B = [ a 11 b 11 + a 12 b 21 + a 13 b 31 a 21 b 11 + a 22 b 21 + a 23 b 31 a 11 b 12 + a 12 b 22 + a 13 b 32 a 21 b 12 + a 22 b 22 + a 23 b 32 ] C_{2\times2}=AB=\left[\begin{matrix}a_{11}b_{11}+a_{12}b_{21}+a_{13}b_{31}&a_{21}b_{11}+a_{22}b_{21}+a_{23}b_{31}\\a_{11}b_{12}+a_{12}b_{22}+a_{13}b_{32}&a_{21}b_{12}+a_{22}b_{22}+a_{23}b_{32}\\\end{matrix}\right] C2×2=AB=[a11b11+a12b21+a13b31a11b12+a12b22+a13b32a21b11+a22b21+a23b31a21b12+a22b22+a23b32]
下面直接给出求解本题的完整代码:
/*MT2224 矩阵乘法
*/ #include<bits/stdc++.h>
using namespace std;const int N = 1005;
int mtx1[N][N], mtx2[N][N];// 输入一个 m*n 的矩阵
void getMatrix(int m, int n, int matrix[][N])
{for(int i=1; i<=m; i++)for(int j=1; j<=n; j++)cin>>matrix[i][j];
}// 执行矩阵乘法并打印结果
void matrixMuiti(int l, int m, int n, int matrix1[][N], int matrix2[][N])
{int tmp;for(int i=1; i<=l; i++){for(int j=1; j<=n; j++){tmp = 0;for(int k=1; k<=m; k++)tmp += matrix1[i][k] * matrix2[k][j];cout<<tmp<<" ";}cout<<endl;}
}int main( )
{// 录入数据 int l, m, n;cin>>l>>m>>n;getMatrix(l ,m, mtx1);getMatrix(m, n, mtx2);// 执行矩阵乘法并输出结果matrixMuiti(l, m, n, mtx1, mtx2);return 0;
}
MT2231 越狱
难度:钻石 时间限制:1秒 占用内存:128M
题目描述
监狱有 n n n 个房间,每个房间关押一个犯人,有 m m m 种宗教,每个犯人会信仰其中一种。如果相邻房间中的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱。
答案对1007取模。格式
输入格式:输入一行只有两个整数,分别代表宗教数 m m m 和房间数 n n n。
输出格式:输出一行一个整数代表答案。样例 1
输入:
2 3输出:
6备注
其中: 1 ≤ m ≤ 10 8 , 1 ≤ n ≤ 1010 1\le m\le{10}^8,1≤n≤1010 1≤m≤108,1≤n≤1010。
相关知识点:
排列组合、快速幂
题解
首先对题目的意思进行简单梳理:有 n n n 个并排的人(非环形结构),每个人有且仅有一个信仰,现在有 m m m 种信仰,问相邻两个人具有同一信仰的排列方式有多少种?
“相邻两人具有同一信仰”的排列方式是非常繁杂的,如同信仰的相邻人序列可以取 2、3、……的长度,也可以是中间间隔若干人后出现同信仰的相邻人序列。因此,对这道题采取直接求解法是困难的。此时,我们可以求该事件的对立事件方案数,并用总排列数减去该数即可(总排列数为 m n m^n mn,第 i i i 个人有 m m m 种选择)。
“存在相邻两人具有同一信仰”的对立事件是“任何相邻的人的信仰彼此不同”。在这种情况下,第一个人可以是任意信仰(即 a 1 = m a_1=m a1=m),接下来第二个人只要不和前一个人信仰相同即可(即 a 2 = m − 1 a_2=m-1 a2=m−1),第三个人同样只需要和其前一个人的信仰不同(即 a 3 = m − 1 a_3=m-1 a3=m−1)……可以发现,后续每个人都只需要满足不和其前一个人的信仰相同即可,即 a i = m − 1 ( i = 2 , 3 , … , n ) a_i=m-1\left(i=2,3,\ldots,n\right) ai=m−1(i=2,3,…,n)。于是可得到“任何相邻的人的信仰彼此不同”的排列方案共有 ∏ i = 1 n a i = m ( m − 1 ) n − 1 \prod_{i=1}^{n}a_i=m\left(m-1\right)^{n-1} ∏i=1nai=m(m−1)n−1 种。
所以,“相邻两人具有同一信仰”的排列方案共有 m n − m ( m − 1 ) n − 1 m^n-m\left(m-1\right)^{n-1} mn−m(m−1)n−1 种。
从题目给出的数据范围看,所计算的两个值都非常庞大(无标准的数据类型可以存储),因此答案要求对指定数取模。于是这里就涉及到了模运算的一些性质:
- 加法: ( a + b ) % M = ( ( a % M ) + ( b % M ) ) \left(a+b\right)\%M=\left(\left(a\%M\right)+\left(b\%M\right)\right)%M (a+b)%M=((a%M)+(b%M))
- 减法: ( a − b ) % M = ( ( a % M ) − ( b % M ) ) \left(a-b\right)\%M=\left(\left(a\%M\right)-\left(b\%M\right)\right)%M (a−b)%M=((a%M)−(b%M))
- 乘法: ( a × b ) % M = ( ( a % M ) × ( b % M ) ) \left(a\times b\right)\%M=\left(\left(a\%M\right)\times\left(b\%M\right)\right)%M (a×b)%M=((a%M)×(b%M))
从模运算的乘法律可以看出,在计算乘幂时,可以边取余边计算,进而降低中间环节求得的数据范围,使标准数据类型可用。
通过循环求乘幂运算的方法很简单,此处主要探讨快速幂的实现。
幂运算 m n m^n mn 有一个特性:每次叠乘时的乘数一致。因此,可通过在已算出的较低次数的乘幂结果上进行新的叠乘运算来降低总计算次数。说简单点就是, m , m 2 , ( m 2 ) 2 , … m,\ m^2,\left(m^2\right)^2,\ldots m, m2,(m2)2,… 直到 m n m^n mn。这实际上是一种分治的思想,可采用基于递归的方式实现:
int fastPow(int m, int n)
{if(n == 1) return m;int tmp = fastPow(m, n/2);// 幂为奇数 if(n&1) return tmp*tmp*m;// 幂为偶数 else return tmp*tmp;
}
不难看出,采取这种方法实现快速幂的时间复杂度为 O ( l o g 2 n ) O\left({log}_2{n}\right) O(log2n)。
另一种基于位运算的快速幂实现方法则从幂的二进制形式出发,通过对幂逐步移位,来实现对幂的分解并完成累乘。例如,对 m 11 m^{11} m11,首先将幂转换为二进制得到 11 10 = 1011 2 = 2 3 + 2 1 + 2 0 {11}_{10}={1011}_2=2^3+2^1+2^0 1110=10112=23+21+20,这说明对乘幂 m 11 m^{11} m11 的计算只需要将其幂 11 计算到 3 次即可。下面用一个实际例子予以说明,计算 m 11 m^{11} m11(初始化乘幂结果为 a n s = 1 ans=1 ans=1,当前底数为 b a s e = m base=m base=m)的流程如下:
- 取幂 1011 的末位得到 1 说明当前需要进行一次累乘,于是更新 a n s = a n s ∗ b a s e = m ans\ =\ ans\ast base\ =\ m ans = ans∗base = m。在这之后需要更新底数,于是 b a s e = b a s e ∗ b a s e = m 2 base\ =\ base\ast base\ =m^2 base = base∗base =m2。最后将幂 1011 向右移一个单位得到 101;
- 取幂 101 的末位得到 1 说明当前需要进行一次累乘,于是更新 a n s = a n s ∗ b a s e = m 3 ans\ =\ ans\ast base\ =\ m^3 ans = ans∗base = m3。在这之后需要更新底数,于是 b a s e = b a s e ∗ b a s e = m 4 base\ =\ base\ast base\ =m^4 base = base∗base =m4 。最后将幂 101 向右移一个单位得到 10;
- 取幂 10 的末位得到 0 说明当前不需要进行累乘,于是直接更新底数 b a s e = b a s e ∗ b a s e = m 8 base\ =\ base\ast base\ =m^8 base = base∗base =m8。最后将幂 10 向右移一个单位得到 1;
- 取幂 1 的末位得到 1 说明当前需要进行一次累乘,于是更新 a n s = a n s ∗ b a s e = m 11 ans\ =\ ans\ast base\ =\ m^{11} ans = ans∗base = m11。在这之后需要更新底数,于是 b a s e = b a s e ∗ b a s e = m 16 base\ =\ base\ast base\ =m^{16} base = base∗base =m16。最后将幂 1 向右移一个单位得到 0;
- 由于幂已经为 0,故退出算法,输出最终的乘幂结果。
基于位运算的快速幂具有更快的迭代速度,因此在现实中更为常用。下面给出其具体实现(注意,底数 b a s e base base 可以直接在参数 m m m 的基础上直接进行变换,而无需单独设置一个变量):
int fastPow(int m, int n)
{int ans = 1;while(n){if(n&1) ans *= m;// 更新底数m *= m;// 更新幂n >>= 1;}return ans;
}
对本题而言,由于涉及到的乘幂运算具有较大数据范围,因此需要在求幂的过程中加入取模运算。下面直接给出基于以上思路得到的求解本题的完整代码:
/*MT2231 越狱 排列问题:m^n - m*(m-1)^(n-1)
*/ #include<bits/stdc++.h>
using namespace std;const int MOD = 1007;// 含取模运算的快速幂模板
int fastPow(long m, long n, long mod)
{m %= mod;int res = 1;while (n){if (n & 1)res = (res * m) % mod;m = (m * m) % mod;n >>= 1;}return res;
}int main( )
{// 录入数据 long m, n;cin>>m>>n; // 输出结果(注意为了防止出现负数,需要加上 MOD 后再取模)cout<<(fastPow(m, n, MOD)-m*fastPow(m-1, n-1, MOD)%MOD + MOD)%MOD<<endl; return 0;
}
MT2232 找朋友
难度:黄金 时间限制:5秒 占用内存:128M
题目描述
将 n n n 个人分成 m m m 组,每组至少一人,在比赛结束时,同一组的人两两之间都会成为朋友,不同分组的分组方案得到的朋友对数不同。你的任务是求出最小和最大的朋友对数。
格式
输入格式:两个正整数 n , m n,\ m n, m;
输出格式:两个整数表示答案。
样例 1
输入:
5 1
输出:
10 10
备注
其中: 1 ≤ m ≤ n ≤ 10 9 1\le m\le n\le{10}^9 1≤m≤n≤109;
相关知识点:
排列组合
题解
题目让我们将 n n n 个人分进 m m m 个组中,而在同一个组中的所有人都将成为朋友(即任意两人相互认识)。然后题目的要求是:求在给定人和组数情况下的最小朋友数和最大朋友数。
首先要弄清楚朋友数的含义。例如, n n n 个人一组时有多少朋友数?实际上,这个问题等价于: n n n 个顶点最多能形成多少条边?

以某个点为视角,它可以与除自身以外的任何顶点连线得到一条边,因此对这个点而言,它能形成 n − 1 n-1 n−1 条边。一共有 n n n 个顶点,则一共能形成 n ( n − 1 ) n\left(n-1\right) n(n−1) 条边。但是,由于每条边都有两个顶点,因此在按这样的算法(遍历点)统计边数时所有边都会被额外记录一次。所以 n n n 个顶点最多能形成 n ( n − 1 ) 2 \frac{n\left(n-1\right)}{2} 2n(n−1) 条边。
当然,也可以从排列组合的角度来求解。“ n n n 个顶点最多能形成多少条边”等价于“从 n n n 个顶点中选择 2 个顶点有多少种选法?”显然,这个问题的答案是 C n 2 = n ( n − 1 ) 2 C_n^2=\frac{n\left(n-1\right)}{2} Cn2=2n(n−1)。
而本题有所不同,它要求计算将 n n n 个人分进 m m m 个组时,整个系统内的最小和最大朋友数。那什么时候系统内的朋友数最少,什么时候又最大呢?前面提到单个组内的人数(假设为 x x x )能形成的朋友数为 x ( x − 1 ) 2 \frac{x\left(x-1\right)}{2} 2x(x−1)。这是一个关于人数的二次函数,因此其在人数更多的情况下会产生比人数更少时更多的朋友数。所以,为了使整个系统内的朋友数尽可能少,就需要让各个分组内的人数较为平均;为了使整个系统内的朋友数尽可能多,就需要让一个分组得到尽可能多的人,而剩余分组则仅分一人。基于此,可分别有以下结论:
- 最小朋友数:将 n n n 个人平均分配到 m m m 个组中。则 n % m n\%m n%m 的组会分到 n m + 1 \frac{n}{m}+1 mn+1 个人;剩余 m − n % m m-n\%m m−n%m 个组将分到 n m \frac{n}{m} mn(设为 t m p tmp tmp)个人。因此,系统内的总朋友数为: ( n % m ) ∗ C t m p + 1 2 + ( m − n % m ) ∗ C t m p 2 (n\%m)*C_{tmp+1}^2+(m-n\%m)*C_{tmp}^2 (n%m)∗Ctmp+12+(m−n%m)∗Ctmp2。
- 最大朋友数:将 m − 1 m-1 m−1 个人分到 m − 1 m-1 m−1 个组中(各组一个人),再将剩余 n − ( m − 1 ) n-(m-1) n−(m−1) 个人分至最后一个组中。则前面的 m − 1 m-1 m−1 个组不会产生朋友数,而剩余一个组将产生 C n − ( m − 1 ) 2 C_{n-(m-1)}^2 Cn−(m−1)2个朋友数。
下面给出基于以上思路得到的完整代码:
/*MT2232 找朋友
*/
#include<bits/stdc++.h>
using namespace std;int main( )
{// 录入数据 int n, m;cin>>n>>m;// 最大的朋友对数 long tmp = n-(m-1);long maxPairs = tmp*(tmp-1)/2;// 最小的朋友对数 tmp = n / m;long minPairs = (m-(n%m))*tmp*(tmp-1)/2 + (n%m)*tmp*(tmp+1)/2;// 输出结果cout<<minPairs<<" "<<maxPairs<<endl; return 0;
}
MT2233 盒子与球
难度:黄金 时间限制:1秒 占用内存:128M
题目描述
现有 r r r 个互不相同的盒子和 n n n 个互不相同的球,要将这 n n n 个球放入 r r r 个盒子中,且不允许有空盒子。请求出有多少种不同的放法。
两种放法不同当且仅当存在一个球使得该球在两种放法中放入了不同的盒子。
格式
输入格式:输入一行只有两个正整数,分别代表 n n n 和 r r r。
输出格式:输出一行一个整数代表答案。样例 1
输入:
3 2输出:
6
备注
其中: 1 ≤ r ≤ n ≤ 10 1\le r\le n\le10 1≤r≤n≤10。
相关知识点:
排列组合、第二类斯特林数
题解
这是一道经典的盒子放球问题,简化描述如下: n n n 个不同的球放入 r r r 个不同的盒子,使每个盒子至少有一个球,问总的放置方案。
有关此类问题的一个总结性帖子:n 球放 m 盒子问题汇总。
这实际上是一个集合划分问题,为解决此类问题定义第二类斯特林数 { n m } \begin{Bmatrix}n \\ m\end{Bmatrix} {nm} ,表示将 n n n 个不同元素划分成 m m m 个非空集合(读作 “ n n n 子集 m m m”)。由于该定义是将元素分成若干集合,故又将第二类斯特林数称为斯特林子集数。从该定义不难看出这类数的一些特例:
- 当 n < m n<m n<m 时 { n m } = 0 \begin{Bmatrix}n \\ m\end{Bmatrix}=0 {nm}=0。因为总存在集合没有任何元素;
- 当 n ≥ 1 n\geq1 n≥1 时 { n 1 } = 0 \begin{Bmatrix}n \\ 1\end{Bmatrix}=0 {n1}=0。因为只有一种划分方案,即将所有元素视为一个集合;
- 当 n = m 时 n=m\ 时 n=m 时 { n m } = 1 \begin{Bmatrix}n \\ m\end{Bmatrix}=1 {nm}=1。因为只有一种划分方案,即各元素单独形成一个集合;
- 当 n ≥ 2 n\geq2 n≥2 时 { n 2 } = 2 n − 1 − 1 \begin{Bmatrix}n \\ 2\end{Bmatrix}=2^{n-1}-1 {n2}=2n−1−1。在这种情况下,可将某一元素视为一个集合 Φ \mathrm{\Phi} Φ,其他元素视为另一个集合 Ω \mathrm{\Omega} Ω,接下来对集合 Φ \mathrm{\Phi} Φ 中的 n − 1 n-1 n−1 个元素而言,每个元素都有 2 种选择:要么加入集合 Φ \mathrm{\Phi} Φ,要么留在集合 Ω \mathrm{\Omega} Ω 中,因此这将产生 2 n − 1 2^{n-1} 2n−1 种组合方案。但是,这里面包含了全部元素都被分至集合 Φ \mathrm{\Phi} Φ 中的情况,因此要再减去 1。
接下来我们讨论第二类斯特林数的递推关系。还是以 “将 n n n 个元素划分成 m m m 个非空集合” 为例,假设现在我们要对第 n n n 个元素进行分配,那么它面对的场景只有两种情况:
- 前面 n − 1 n-1 n−1 个元素形成了 m − 1 m-1 m−1 个集合。在这种情况下,要得到 m m m 个非空集合就只能将第 n n n 个元素单独形成一个集合,只有这一种方案,故其总方案数为 { n − 1 m − 1 } \begin{Bmatrix}n-1 \\ m-1\end{Bmatrix} {n−1m−1}。
- 前面 n − 1 n-1 n−1 个元素形成了 m m m 个集合。在这种情况下,第 n n n 个元素可任选一个集合加入,共有 m m m 种选法,故总方案数为 m ∗ { n m } m*\begin{Bmatrix}n \\ m\end{Bmatrix} m∗{nm}。
于是可得到第二类斯特林数的递推关系:
{ n m } = { n − 1 m − 1 } + m { n − 1 m } , n ≥ 1 \begin{Bmatrix}n \\ m\end{Bmatrix}=\begin{Bmatrix}n-1 \\ m-1\end{Bmatrix}+m\begin{Bmatrix}n-1 \\ m\end{Bmatrix},n≥1 {nm}={n−1m−1}+m{n−1m},n≥1
有了递推关系和初始化条件便能计算第二类斯特林数:
// 第二类斯特林数(递归实现)
int getStirling(int n, int m)
{if(n<m) return 0;else if((n==m) || (m==1)) return 1;else if(m==2) return pow(2, (n-1))-1;else return getStirling(n-1, m-1) + m*getStirling(n-1, m);
}
注意到一点,本题中的球和盒子都是不同的,而第二类斯特林数仅认定元素之间不同(换言之,用第二类斯特林数计算盒子放球问题时,它得到的结果是盒同而球不同)。为此,我们需要在第二类斯特林数的基础之上再乘以盒子的全排列方案数,即有:
m ! { n m } m!\begin{Bmatrix}n \\ m\end{Bmatrix} m!{nm}
这便是将 n n n 个不同球放入 m m m 个不同盒子的总方案数。
下面给出基于以上思路得到的求解本题的完整代码:
/*MT2233 盒子与球 分球问题、第二类斯特林数
*/ #include<bits/stdc++.h>
using namespace std;// 第二类斯特林数(递归实现)
int getStirling(int n, int m)
{if(n<m) return 0;else if((n==m) || (m==1)) return 1;else if(m==2) return pow(2, (n-1))-1;else return getStirling(n-1, m-1) + m*getStirling(n-1, m);
}
// 阶乘(递归实现)
int getFactorial(int n){if(n==1) return 1;else return n*getFactorial(n-1);
}int main( )
{// 录入数据 int n, r;cin>>n>>r;// 输出结果cout<<getFactorial(r)*getStirling(n, r)<<endl; return 0;
}
MT2234 点餐
难度:黄金 时间限制:1秒 占用内存:128M
题目描述
小码哥和他的两个朋友一起去吃饭,他们决定每个人先从菜单上选几道菜,然后点三个人都选中的菜。假设菜单中有 n n n 道菜,他们三人分别点了 a , b , c a,\ b,\ c a, b, c 道菜,小码哥想知道是否有可能不存在三个人都选中的菜。
格式
输入格式:一行,4 个以空格分隔的正整数 n , a , b , c n,\ a,\ b,\ c n, a, b, c 满足 0 < a , b , c ≤ n ≤ 1000 0<a,\ b,\ c\le n\le1000 0<a, b, c≤n≤1000。
输出格式:一行,若可能不存三个人都选中的菜就输出YES,否则输出NO。样例 1
输入:
5 3 4 4输出:
NO
相关知识点:
排列组合
题解
求解这道题一定要理解题目所说 “是否有可能不存在三人都选中的菜” 的含义。例如,现在有 5 道菜,三个人分别点了 2、3、4 道菜,则我们需要考虑是否存在一种选菜方案使 “不存在三人都选中的菜” 这种局面出现。例如,一种可能的 “巧合” 如下:

在上面的选菜方案中,没有任何一个菜被三人同时选中,因此对原问题而言,我们的回答是 “YES”。
又比如,现在有 5 道菜,三个人分别点了 2、4、4 道菜,其中有两个人的选菜方案如下:

接下来对第三个人而言,假设他已经知道了另外两个人的选菜方案(具有上帝视角),则为了使 “不存在三人都选中的菜” 这种局面出现,那他就只能选择 “红烧肉” 和 “青菜汤”。

因此对原问题而言,在这样假设下的回答依然是 “YES”。从这里可以看出,原问题是一个 “证存在” 的题设,因此我们在求解时要做的假设是这三个人都足够聪明且足够有默契(相当于直接假设他们彼此可交流)。
注意到一件事,如果给第三个人再多增加一道菜(即现在三人点菜数为 3、4、4),则接下来无论怎样安排每个人的选菜方案,始终会存在某个菜被三人都点一次。即,对原问题回答 “NO”。
可以看出,如果要使得 “不存在三人都选中的菜” 的局面出现,相当于每个菜最多会被点两次。考虑极限情况:即每个菜恰好被点两次。在这种情况下,相当于每个人点的菜的总数之和恰好为总菜品的 2 倍(类似于上图中的情况)。基于此,一旦所有人点的菜的总数之和再多出 1,都会使得某个菜会被点 3 次。因此,不难发现该问题的答案仅取决于 “所有人点的菜的总数之和” 与 “菜品总数” 的大小关系。基于此,可得到求解本题的完整代码:
/*MT2234 点餐
*/ #include<bits/stdc++.h>
using namespace std;int main( )
{// 录入数据 int n, a, b, c;cin>>n>>a>>b>>c;// 输出结果 if(a+b+c > 2*n) cout<<"NO"<<endl;else cout<<"YES"<<endl;return 0;
}
END
相关文章:
【马蹄集】—— 概率论专题:第二类斯特林数
概率论专题:第二类斯特林数 目录 MT2224 矩阵乘法MT2231 越狱MT2232 找朋友MT2233 盒子与球MT2234 点餐 MT2224 矩阵乘法 难度:黄金 时间限制:5秒 占用内存:128M 题目描述 输入两个矩阵,第一个矩阵尺寸为 l…...
spring中基础核心接口总结
理解这几个接口,及其实现类就可以快速了解spring,具体的用法参考其他spring资料 1.BeanFactory最基础最核心的接口 重要的实现类有:XmlBeanFactory,以及ApplicationContext接口下的类 2.Resource接口,可以通用地访问文件资源 1)ClassPathResource:读取…...
最新Tuxera NTFS2024破解版mac读写NTFS磁盘工具
Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下,MacOSX只能实现对NTFS的读取功能,Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2024完美兼容最新版本的MacOS 11 Big Sur,在M1芯片…...
【标准化封装 SOT系列 】 E SOT-89
〇、SOT-89 这个封装也比较常见,但并不易错。 一、E部分 SOT-89 参数 pin-pin 间距1.5mm body size 4.52.5 二、符合当前标准的典型举例 名称pin 数厂家 body DE矩形 (mm)SOT-894Mini-Circuits – PGA-102 — 4.39/4.62.29/2.59 上图 MiniCircuits 也称DF78…...
【建立单链表:头插法,尾插法;循环列表,带尾指针的循环链表合并(将Tb合并在Ta之后)】
文章目录 一、单链表的基本操作的实现1.建立单链表:头插法----元素插入在链表头部,也叫头插法。2.建立单链表:尾插法----元素插入在链表尾部,也叫尾插法。 二、线性表的链式表示和实现1.循环列表2.带尾指针的循环链表合并…...
图论+线性基高斯消元与主元:1019T2 / P4151
http://cplusoj.com/d/senior/p/SS231019B 相当于图上选一条链和一堆环 考虑dfs生成树。 则链是两条从根出发的链 环是每条返祖边组成的环 所以环和链的异或和可以求出来 链的放到线性基里 然后线性基通过高斯消元求主元(贪心思想,主元可以令那一位…...
Django REST Framework完整教程-RESTful规范-序列化和反序列数据-数据视图
文章目录 1.简介及安装2.案例模型2.1.创建模型2.2.安装mysql必要组件2.3.管理后台转中文2.4.启动后台 3.数据序列化4.RESTful规范4.1.协议、域名和版本4.2.uri(统一资源标识符)4.3.查增删改4.4.过滤信息(Filtering)4.5.状态码(Status Codes&a…...
float、double类型的转化和判断为零问题
1、将字符串转化为float、double 浮点数在内存中的存储机制和整形数据不同,有舍入误差,在计算机中用近似表示任意某个实数。具体来说,这个数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2&…...
强大的虚拟机软件 VMware Fusion Pro 13中文最新 for mac
VMware Fusion Pro是一款虚拟化软件,它允许在Mac电脑上同时运行Windows和其他操作系统,而无需重启电脑,它采用了领先的虚拟化技术,能够保证在Mac电脑在同时运行多个操作系统时表现出极高的效率和稳定性。 VMware Fusion Pro具有以…...
SystemVerilog Assertions应用指南 Chapter1.37 使用局部变量的SVA
在序列或者属性的内部可以局部定义变量,而且可以对这种变量进行赋值。变量接着子序列放置,用逗号隔开。如果子序列匹配,那么变量赋值语句执行。每次序列被尝试匹配时,会产生变量的一个新的备份。 module cubed(enable1, a, aa, clk);input logic [7:0] a; input logic enable1,…...
Linux实现无需手动输入密码的自动化SSH身份验证
SSH密钥身份验证是一种安全的方式,使您能够在无需手动输入密码的情况下连接到远程服务器。以下是如何设置SSH密钥身份验证,以便您的脚本能够自动运行: 步骤 生成SSH密钥对: 在您的本地系统上生成SSH密钥对。如果您尚未生成,请使用…...
CSS 效果 圆形里一个文字居中
效果实现源码: 宽度,高度必须确认,且相等 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>.circlew {width: 45px;height: 45p…...
排序算法,冒泡排序算法及优化,选择排序SelectionSort,快速排序(递归-分区)
一、冒泡排序算法: 介绍: 冒泡排序(Bubble Sort)是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需…...
编写内联函数求解 2x²+4x+5的值,并用主函数调用该函数
动态内存分配可以根据实际需要在程序运行过程中动态地申请内存空间,这种内存空间的分配和释放是由程序员自己管理的,因此也被称为手动内存分配。 C++ 中,动态内存的分配和释放是通过 new 和 delete 操作符进行的。new 操作符用于在堆内存上为对象动态分配空间,dele…...
【Release】Photoshop ICO file format plug-in 3.0
【Introduction】 The Photoshop ICO plug-in is a file format plug-in developed for Photoshop, which allows Photoshop to directly read and write ICO format files. Because Photoshop has powerful pixel bitmap editing functions, it has many users and a good us…...
List.of() Vs Arrays.asList()
java中list.of和Arrays.asList方法有什么区别? 简介 Java 提供了几种用于创建列表的方便方法,包括 List.of 和 Arrays.aslist。尽管这两种方法都可以很简单的创建集合对象,但它们实际上是有一些显著差异的。本文将介绍 Java 中的 List.of()…...
机器学习-计算数据之间的距离
目录 欧氏距离 欧氏距离应用场景: 聚类分析:在聚类算法中(K-means)中,可以使用欧式距离来衡量数据点之间的相似性或距离,以便于将他们划分到不用的簇中。特征匹配:在计算机视觉和图像处理中,可以使用欧氏…...
Uniapp软件库源码 全新带勋章功能(包含前后端源码)
Uniapp软件库全新带勋章功能,搭建好后台 在前端找到 util 这个文件 把两个js文件上面的填上自己的域名, 电脑需要下载:HBuilderX 登录账号 没有账号就注册账号,然后上传文件,打包选择 “发行” 可以打包app h5等等。…...
陪诊小程序|陪诊小程序关爱健康,无忧陪伴
随着社会发展和人们生活水平的提高,健康问题成为人们关注的焦点。然而,在就医过程中,许多患者常常感到孤独和无助,缺乏得到家人陪伴的温暖与安慰。为了解决这一问题,我们公司开发了一款创新的陪诊小程序软件࿰…...
uni-app小程序使用DCloud(插件市场)流程
一、DCloud(插件市场) DCloud 是uni-app官方插件市场,里面有官方、团队、个人发布的众多插件,包括uni-ui、uni-pay 等。而像uni-ui这种大型组件库都有官方文档可参考,但一些团队或个人发布的小型插件没有文档…...
数字考古:MS-DOS源代码中的三重时空对话
数字考古:MS-DOS源代码中的三重时空对话 【免费下载链接】MS-DOS The original sources of MS-DOS 1.25, 2.0, and 4.0 for reference purposes 项目地址: https://gitcode.com/GitHub_Trending/ms/MS-DOS 在计算机历史的尘埃中,MS-DOS的源代码如…...
视觉推理技术:CodeV框架原理与工业实践
1. 视觉推理技术的现状与挑战视觉推理作为多模态人工智能的核心能力,正在经历从静态识别到动态交互的范式转变。当前主流方法主要分为两类:端到端模型和工具增强型系统。端到端模型如Qwen2.5-VL-7B虽然实现了感知与推理的联合优化,但在处理高…...
如何快速在云端启动VSCode:colabcode 5分钟入门指南
如何快速在云端启动VSCode:colabcode 5分钟入门指南 【免费下载链接】colabcode Run VSCode (codeserver) on Google Colab or Kaggle Notebooks 项目地址: https://gitcode.com/gh_mirrors/co/colabcode colabcode是一个强大的工具,能够帮助用户…...
AI模型版本原子回滚、训练-推理环境一致性校验、分布式LoRA微调调度器——Docker AI Toolkit 2026这9个硬核特性,90%工程师尚未启用
更多请点击: https://intelliparadigm.com 第一章:Docker AI Toolkit 2026核心架构演进与安装部署 Docker AI Toolkit 2026(简称 DAIT-2026)标志着容器化AI工作流从“可运行”迈向“可推理、可编排、可审计”的关键跃迁。其核心架…...
WPS-Zotero插件:实现跨平台文献引用的技术解决方案
WPS-Zotero插件:实现跨平台文献引用的技术解决方案 【免费下载链接】WPS-Zotero An add-on for WPS Writer to integrate with Zotero. 项目地址: https://gitcode.com/gh_mirrors/wp/WPS-Zotero WPS-Zotero插件是一个专为WPS Writer设计的扩展工具ÿ…...
树莓派CM4工业一体机:硬件解析与应用实践
1. 产品概述:基于树莓派CM4的工业级一体机Chipsee AIO-CM4-156是一款面向工业场景设计的全功能一体式计算机,其核心采用了树莓派Compute Module 4(CM4)作为运算单元。作为前代10.1英寸型号的升级版本,这款15.6英寸设备…...
GoPro WiFi Hack与OpenGoPro对比分析:选择最适合你的开发方案
GoPro WiFi Hack与OpenGoPro对比分析:选择最适合你的开发方案 【免费下载链接】goprowifihack Unofficial GoPro WiFi API Documentation - HTTP GET requests for commands, status, livestreaming and media query. 项目地址: https://gitcode.com/gh_mirrors/g…...
GHelper:轻量级华硕笔记本控制工具完整使用指南
GHelper:轻量级华硕笔记本控制工具完整使用指南 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, an…...
Arducam OCam AI相机与边缘计算实践解析
1. Arducam OCam AI相机:实时视频流上下文增强的硬件解析 作为一款专为边缘AI设计的智能相机,Arducam OCam在硬件层面实现了多项创新突破。其核心搭载的3 TOPS算力AI加速器(相当于每秒3万亿次运算)使其能够在设备端直接处理2K分辨…...
NLP文本预处理技术与Keras实践指南
1. 文本数据预处理的核心挑战在自然语言处理(NLP)领域工作时,我经常遇到这样的场景:拿到一批原始文本数据时,它们可能包含社交媒体评论、新闻文章或产品描述等各种形式。这些数据通常存在大小写混乱、特殊符号、停用词…...
