链接: https://www.nowcoder.com/acm/contest/202#question
牛客国庆集训派对Day2
- A. 矩阵乘法(分块)
- F. 平衡二叉树(数据结构)
- H. 卡牌游戏(数论-期望)
A. 矩阵乘法(分块)
题意: 给两个矩阵
A
,
B
A, B
A,B,
A
A
A 是十进制矩阵,
B
B
B 是二进制矩阵,问两个矩阵相乘之后得到的结果矩阵的每个元素的异或和。
思路: 因为
B
B
B 是二进制矩阵,
B
B
B 矩阵最多只有 64 行,分块后,它的组合情况其实很少。 若对
A
A
A 分块, 每行每 8 个分一块,那
B
B
B 中就只有 256 种情况。 对矩阵
A
A
A 每行最多 8 个块的 256 种情况预处理,预处理时采用类似状压dp的方式,每个预处理的数只需要在之前的基础上加上二进制最后一位 1 对应的没被处理过的数就行了。(注意二进制全是0的时候一定是0不需要考虑)相乘的结果就是每行中的每块值对应查表,在加起来就是了。复杂度O(8 * n *m)。
(比赛时不会,看了题解,又看了别人代码才写出来。后来听说暴力也能过,我只能给牛客的评测机点个赞了。)
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
using namespace std;
const int MAXN = 5000;
const int MAXP = 100;
int f[MAXN][10][300];
int n, p, m;
int A[MAXN][MAXP];
int C[MAXN][MAXN];
unsigned long long B[MAXN];
int num[300];
int main(int argc, char const *argv[])
{
scanf("%d%d%d", &n, &p, &m);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < p; ++j) {
scanf("%x", &A[i][j]);
}
}
char c[100];
for (int i = 0; i < m; ++i) {
scanf("%s", c);
for (int j = p-1; j >= 0; --j) {
B[i] <<= 1;
B[i] += (c[j]^'0');
}
}
for (int i = 1; i < 8; ++i) {
num[1<<i] = i;
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 8; ++j) {
for (int k = 1; k < 256; ++k) {
f[i][j][k] = f[i][j][k^lowbit(k)] + A[i][j*8+num[lowbit(k)]];
}
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
for (int k = 0; k < 8; ++k) {
C[i][j] += f[i][k][B[j]>>(k*8)&255];
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
ans ^= C[i][j];
}
}
cout<<ans<<endl;
return 0;
}
F. 平衡二叉树(数据结构)
题意: 满足左右子树高度差不超过
d
d
d 的二叉树称为平衡二叉树。不平衡度是树中所有节点的左右子树的节点数之差的最大值。给定
d
,
n
d, n
d,n ,求不平衡度的最大值。
思路:
1.当
d
>
=
n
−
1
d >= n-1
d>=n−1 时,可以假定根节点的左子树是满二叉树,右子树是空树,直接输出 高度
n
−
1
n-1
n−1 的满二叉树的节点个数
2
n
−
1
−
1
2^{n-1} -1
2n−1−1 。
2.当
d
<
n
−
1
d < n-1
d<n−1 时, 仿照之前的思路,假定根节点的左子树是满二叉树,右子树是符合平衡要求的节点最少的平衡二叉树。还记得最小平衡二叉树节点数公式吗
f
(
h
)
=
{
h
h
≤
d
f
(
h
−
1
)
+
f
(
h
−
1
−
d
)
+
1
h
>
d
f(h)= \begin{cases} h & \text { $h \leq d$ } \\ f(h-1) + f(h-1-d) + 1 & \text{ $h > d$ } \end{cases}
f(h)={hf(h−1)+f(h−1−d)+1 h≤d h>d
左子树的高度是
n
−
1
n-1
n−1 , 所以右子树的高度只需要
n
−
1
−
d
n-1-d
n−1−d 就可以了,所以答案即
2
n
−
1
−
1
−
f
(
n
−
1
−
d
)
2^{n-1} - 1 - f(n-1-d)
2n−1−1−f(n−1−d) 。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n, d;
LL power(LL x, LL n) {
LL res = 1;
while(n) {
if(n & 1) {
res = (res*x);
}
x = x*x;
n >>= 1;
}
return res;
}
int main(int argc, char const *argv[])
{
cin>>n>>d;
LL f[100];
if(n == 0) {
cout<<0<<endl;
return 0;
}
if(d >= n-1) {
cout<<power(2, n-1)-1<<endl;
return 0;
}
for (LL i = 0; i <= d; ++i) {
f[i] = i;
}
for (LL i = d+1; i <= n-1-d; ++i) {
f[i] = f[i-1] + f[i-1-d] + 1;
}
LL ans = power(2, n-1)-1 - f[n-1-d];
cout<<ans<<endl;
return 0;
}
H. 卡牌游戏(数论-期望)
题意 :
N
N
N 种牌,
M
M
M 种稀有,每抽一次,会随机从
N
N
N 种牌选择一个,但
M
M
M 种牌不会重复抽到, 现在想得到
K
K
K 种稀有卡牌,问抽牌的次数的期望是多少。
思路:
- 先考虑
K
=
=
1
K == 1
K==1 的情况,
第一次抽到的概率是
M
N
\frac M N
NM
第二次抽到的概率是
N
−
M
N
∗
M
N
\frac {N-M} N * \frac M N
NN−M∗NM
…
第
n
n
n 次抽到的概率是
(
N
−
M
N
)
n
−
1
∗
M
N
(\frac {N-M} N )^{n-1}* \frac M N
(NN−M)n−1∗NM
期望
E
=
1
∗
M
N
+
2
∗
N
−
M
N
∗
M
N
+
.
.
.
+
n
∗
(
N
−
M
N
)
n
−
1
∗
M
N
E = 1 * \frac M N + 2 * \frac {N-M} N * \frac M N + ... + n * (\frac {N- M} N )^{n-1}* \frac M N
E=1∗NM+2∗NN−M∗NM+...+n∗(NN−M)n−1∗NM
E
=
1
−
(
N
−
M
N
)
n
1
−
N
−
M
N
−
n
∗
(
N
−
M
N
)
n
E = \frac {1 - (\frac {N-M} N)^n} {1 - \frac {N-M} N} - n * (\frac {N-M} N)^n
E=1−NN−M1−(NN−M)n−n∗(NN−M)n
当
n
n
n 趋于无穷时
E
=
N
M
E = \frac N M
E=MN - 当
K
=
=
2
K == 2
K==2 时, 因为
M
M
M 种稀有牌不会重复得到, 所以可以分解为两个子问题, 即可以理解为先从
N
N
N 种牌,
M
M
M 种稀有中得到
1
1
1 种, 再从
N
−
1
N-1
N−1种牌,
M
−
1
M-1
M−1 种稀有中得到
1
1
1 种。所以
E
=
N
M
+
N
−
1
M
−
1
E = \frac N M + \frac {N-1} {M-1}
E=MN+M−1N−1
- 以此类推, 当
K
=
=
K
K == K
K==K 时,
E
=
∑
i
=
0
K
−
1
N
−
i
M
−
i
E = \sum ^{K-1} _{i=0}\frac {N-i} {M-i}
E=∑i=0K−1M−iN−i
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t, cas = 0;
double n, m, k;
cin>>t;
while(t--) {
cin>>n>>m>>k;
double ans = 0;
for(int i = 0; i < k; ++i) {
ans += (n-i)/(m-i);
}
cout<<"Case #"<<++cas<<": "<<fixed<<setprecision(12)<<ans<<endl;
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)