The 18th Heilongjiang Provincial Collegiate Programming Contest
A. Magic Computer
看题目猜规律
#include <bits/stdc++.h>
using namespace std;
#define int long long
using vi = vector<int>;
using i32 = int32_t;
const int mod = 998244353;
int power(int x, int y) {
int ans = 1;
while (y) {
if (y & 1) ans = ans * x % mod;
x = x * x % mod, y /= 2;
}
return ans;
}
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int k;
cin >> k, k -= 1;
cout << power( 2 , k ) << "\n";
return 0;
}
E. Ethernet
数据范围有限,可以直接用dfs统计出所有的情况,然后计算概率即可
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
int n, m;
double ans;
void dfs(int u, double p, vector<int> a) {
if (u == n) {
ans += p;
return;
}
if (u <= m) {
double cnt = .0;
for (int i = 1; i <= n; i++) {
if (!a[i]) {
cnt += 1.0;
}
}
for (int i = 1; i < n; i++) {
if (!a[i]) {
a[i] = u;
dfs(u + 1, p * (1.0 / cnt), a);
a[i] = 0;
}
}
} else {
if (a[u] == 0) {
a[u] = u;
dfs(u + 1, p, a);
} else {
double cnt = .0;
for (int i = 1; i <= n; i++) {
if (!a[i]) {
cnt += 1.0;
}
}
for (int i = 1; i < n; i++) {
if (!a[i]) {
a[i] = u;
dfs(u + 1, p * (1.0 / cnt), a);
a[i] = 0;
}
}
}
}
}
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> m;
vector<int> a(n + 1);
dfs(1, 1.0, a);
cout << fixed << setprecision(10) << ans << endl;
return 0;
}
F. Folder
直接统计一下子节点的种类即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
int ans = 0;
vector<int> ve(n + 5);
for (int i = 2; i <= n; ++i) {
int x;
cin >> x;
if (ve[x])ans++;
ve[x]++;
}
cout << ans;
return 0;
}
I. Club
有两类勋章
第一类\(a\)种勋章,每种勋章\(x\)个活动
第二类\(b\)种勋章,每种勋章\(y\)个活动
设\(f_{i,j}\)表示差\(i\)种第一类勋章和\(j\)种第二类勋章所需要的期望次数,因此\(f_{0,0} =0\)
对于枚举到的状态\(f_{i,j}\),选到一种新的概率\(p=\frac{ix + jy}{n}\),期望次数\(E=\frac 1p\)。其中选到第一类的概率是\(\frac{ix}{ix+jy}\),选到第二类的概率是\(\frac{jy}{ix+jy}\),所以
\[f_{i,j} = \frac{ix}{ix+jy} f_{i-1,j} + \frac{jy}{ix+jy} f_{i,j-1} + \frac{n}{ix+jy}
\]
#include <bits/stdc++.h>
using namespace std;
#define int long long
using vi = vector<int>;
using i32 = int32_t;
using ldb = long double;
const int mod = 998244353;
#define DEBUG(x) cerr <<(#x) << " = " << x << "\n";
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, m;
cin >> n >> m;
int x = n / m, y = x + 1;
int a = m + m * x - n, b = m - a;
auto f = vector(a + 1, vector<double>(b + 1));
for (int k = 1, ix, jy, t; k <= m; k++) {
for (int i = 0, j = k; i <= k; i++, j--) {
if (i > a or j > b) continue;
ix = i * x, jy = j * y, t = ix + jy;
f[i][j] = ldb(n) / t;
if (i > 0) f[i][j] += ix * f[i - 1][j] / t;
if (j > 0) f[i][j] += jy * f[i][j - 1] / t;
}
}
cout << fixed << setprecision(10) << f[a][b] << "\n";
return 0;
}