A - 12435
点击查看代码
void solve() {int cnt = 0;int a[6]{};for (int i = 1; i <= 5; ++ i) {std::cin >> a[i];}for (int i = 1; i <= 4; ++ i) {cnt += (a[i] != i && a[i + 1] != i + 1);}if (cnt == 1) {std::cout << "Yes\n";} else {std::cout << "No\n";}
}
B - Geometric Sequence
题意:判断一个数列是不是等比数列。
如果用浮点数计算公比可能因为精度误差导致判断错误,可以分解为分数的形式,因为\(a_i : a_{i + 1} = a_1 : a_2, i \in [1, n]\),那么计算\(gcd\)搞个最简分数判断即可。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}int x = a[0] / std::gcd(a[0], a[1]), y = a[1] / std::gcd(a[0], a[1]);for (int i = 0; i + 1 < n; ++ i) {int d = std::gcd(a[i], a[i + 1]);if (a[i] / d != x || a[i + 1] / d != y) {std::cout << "No\n";return;}}std::cout << "Yes\n";
}
C - Paint to make a rectangle
题意:有一个矩阵,有些地方涂了黑色,有些地方涂了白色,有些没有涂色。问能不能给所有格子涂色后使得所有黑色格子恰好成为一个矩阵。
找出已有的黑色格子的上下左右边界,判断里面有没有白色格子, 如果没有那么我们一定可以让这个子矩阵全是黑色,否则一个白色格子出现在这中间,不可能让黑色格子恰好形成一个矩阵。
点击查看代码
void solve() {int n, m;std::cin >> n >> m;std::vector<std::string> s(n);for (int i = 0; i < n; ++ i) {std::cin >> s[i];}int a = n, b = 0, c = m, d = 0;for (int i = 0; i < n; ++ i) {for (int j = 0; j < m; ++ j) {if (s[i][j] == '#') {a = std::min(a, i);b = std::max(b, i);c = std::min(c, j);d = std::max(d, j);}}}for (int i = 0; i < n; ++ i) {for (int j = 0; j < m; ++ j) {if (s[i][j] == '.' && i >= a && i <= b && j >= c && j <= d) {std::cout << "No\n";return;}}}std::cout << "Yes\n";
}
D - Stone XOR
题意:将\(n\)个数分成若干个集合,求所有情况下每个集合的和的异或和有多少种。
观察到\(n\)很小,可以爆搜。
每次讨论把\(a_i\)放到前面已有的集合还是自己单独分一个集合,复杂度大概是阶乘级别(应该吧)。
不过要吐槽一下卡set而不卡unordered_set。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<i64> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}std::unordered_set<i64> s;std::vector<i64> b;auto dfs = [&](auto self, int u, i64 x) -> void {if (u == n) {s.insert(x);return;}b.push_back(a[u]);self(self, u + 1, x ^ a[u]);b.pop_back();for (auto & y : b) {x ^= y;y += a[u];self(self, u + 1, x ^ y);y -= a[u];x ^= y;}};dfs(dfs, 0, 0);std::cout << s.size() << "\n";
}
E - Vitamin Balance
题意:有\(n\)个物品,所有物品总共分成三种。每个物品有价值和体积,你有\(m\)的容量,求在不超过容量的前提下三种物品的最小价值最大是多少。
分别对三类物品做01背包。然后枚举分给第一种物品多少容量和分给第二种物品多少容量,那么第三种物品的容量可以直接计算。然后取其中最小值的最大值即可。
点击查看代码
void solve() {int n, m;std::cin >> n >> m;std::vector<std::pair<int, int> > a, b, c;for (int i = 0; i < n; ++ i) {int v, t, w;std::cin >> t >> v >> w;if (t == 1) {a.push_back({w, v});} else if (t == 2) {b.push_back({w, v});} else {c.push_back({w, v});}}auto dp = [&](std::vector<std::pair<int, int> > a) -> std::vector<int> {std::vector<int> f(m + 1);for (auto & [w, v] : a) {for (int i = m; i >= w; -- i) {f[i] = std::max(f[i], f[i - w] + v);}}return f;};auto fa = dp(a), fb = dp(b), fc = dp(c);int ans = 0;for (int i = 1; i <= m; ++ i) {for (int j = 1; i + j < m; ++ j) {int k = m - i - j;ans = std::max(ans, std::min({fa[i], fb[j], fc[k]}));}}std::cout << ans << "\n";
}
F - Double Sum 3
待补