回头看|

Ke_scholar

园龄:2年1个月粉丝:30关注:10

2025-02-09 19:10阅读: 6评论: 0推荐: 0

SMU winter 2025 Personal Round 2

SMU winter 2025 Personal Round 2

A. Ichihime and Triangle

思路

\(a, b, c, d\) 单调递增,所以 \(x, y, z\) 也会单调递增。这时只需要满足 \(x + y > z\) 就行了。

我们把 \(x, y\) 取最大值:\(x = b\), \(y = c\)\(z\) 取最小值:\(z = c\)。就是最有可能实现的方案。

这时我们发现 \(x + y > z\),说明一定能实现。所以直接输出 \(b,c, c\) 即可。

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
void solve() {
int a, b, c, d;
cin >> a >> b >> c >> d;
cout << b << " " << c << " " << c << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}

B - Kana and Dragon Quest game

思路

对第一种操作,当 \(x > 20\) 时,该操作会一直减小 \(x\)

所以当 \(x > 20\) 时,我们可以一直执行第一种操作,然后再执行第二种操作,这样能尽可能的减少 \(x\)

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
void solve() {
int x, n, m;
cin >> x >> n >> m;
while (x > 20 && n) {
n --;
x = x / 2 + 10;
}
cout << (x > m * 10 ? "NO\n" : "YES\n");
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}

C - Linova and Kingdom

思路

建立好树,令1号节点的深度是1,然后往下走,当遍历到的点是叶子节点时,该点的贡献是该点到1号节点的距离(\(deep-1\)),当该点不是叶子节点时该点的贡献是\(deep-cnt\)\(cnt\)为算上自己和自己所有子子孙孙且都认为是工业节点的数量)。

这样得到的数组按贡献降序排序,并将前\(k\)个贡献累加即可。

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k;
cin >> n >> k;
vector g(n + 1, vector<int>());
for (int i = 1; i < n; i ++) {
int u, v;
cin >> u >> v;
g[u].emplace_back(v);
g[v].emplace_back(u);
}
vector<int> dep(n + 1), has(n + 1);
auto dfs = [&](auto && self, int u, int fa)->void{
dep[u] = dep[fa] + 1;
has[u] = 1;
for (auto &v : g[u]) {
if (v == fa) continue;
self(self, v, u);
has[u] += has[v];
}
};
dfs(dfs, 1, 0);
vector<int> a(n + 1);
iota(a.begin(), a.end(), 0);
sort(a.begin() + 1, a.end(), [&](auto x, auto y) {
return dep[x] - has[x] > dep[y] - has[y];
});
i64 ans = 0;
for (int i = 1; i <= k; i ++) {
ans += dep[a[i]] - has[a[i]];
}
cout << ans << "\n";
return 0;
}

D - Xenia and Colorful Gems

思路

先枚举其中一个,然后二分找到距离该点较近的几个数,得到两个数后,便可以得知第三个数的范围,在此基础上再去进行二分,然后枚举计算最小值即可。

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
void solve() {
int n[3] {};
for (int i : {0, 1, 2}) {
cin >> n[i];
}
vector has(3, vector<int>());
for (int i : {0, 1, 2}) {
has[i].resize(n[i]);
for (auto &x : has[i]) {
cin >> x;
}
sort(has[i].begin(), has[i].end());
}
i64 ans = LLONG_MAX;
auto ck = [&](int idx)->void{
for (auto &x : has[idx]) {
int ny = lower_bound(has[(idx + 1) % 3].begin(), has[(idx + 1) % 3].end(), x) - has[(idx + 1) % 3].begin();
for (int i = max(0, ny - 5); i < min(n[(idx + 1) % 3], ny + 6); i ++) {
i64 y = has[(idx + 1) % 3][i];
int nz = lower_bound(has[(idx + 2) % 3].begin(), has[(idx + 2) % 3].end(), (x + y) / 2) - has[(idx + 2) % 3].begin();
for (int j = max(0, nz - 5); j < min(n[(idx + 2) % 3], nz + 6); j ++) {
i64 z = has[(idx + 2) % 3][j];
ans = min(ans, (x - y) * (x - y) + (x - z) * (x - z) + (y - z) * (y - z));
}
}
}
};
ck(0);
ck(1);
ck(2);
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}

E - Kaavi and Magic Spell

思路

动态规划,定义状态 \(dp[i][j]\) 表示使用 \(S\) 的前 \(j-i+1\) 个字符构造的字符串恰好覆盖 \(T\) 的第 \(i\)\(j\) 位时的方案数。初始时,若 \(S\) 的第一个字符与 \(T\) 的第 \(k\) 位匹配(或 \(k > m\)),则 \(dp[k][k] = 2\)(两种操作方式)。

对于长度为 \(len\) 的子问题,若当前字符 \(s[len]\) 添加到前端且与 \(T[i]\) 匹配(或 \(i > m\)),则从 \(dp[i+1][j]\) 转移;若添加到后端且与 \(T[j]\) 匹配(或 \(j > m\)),则从 \(dp[i][j-1]\) 转移。最终答案为所有满足 \(1 \leq i \leq j \leq n\)\(j \geq m\)\(dp[1][j]\) 之和。时间复杂度为 \(O(n^2)\),空间复杂度 \(O(n^2)\)

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
//------取模机------//
using i64 = long long;
template<class T>
constexpr T power(T a, i64 b) {
T res {1};
for (; b; b /= 2, a *= a) {
if (b % 2) {
res *= a;
}
}
return res;
} // 快速幂
constexpr i64 mul(i64 a, i64 b, i64 p) {
i64 res = a * b - i64(1.L * a * b / p) * p;
res %= p;
if (res < 0) {
res += p;
}
return res;
} // 取模乘
template<i64 P>
struct MInt {
i64 x;
constexpr MInt() : x {0} {}
constexpr MInt(i64 x) : x {norm(x % getMod())} {}
static i64 Mod;
constexpr static i64 getMod() {
if (P > 0) {
return P;
} else {
return Mod;
}
}
constexpr static void setMod(i64 Mod_) {
Mod = Mod_;
}//只有P<=0, setMod才生效
constexpr i64 norm(i64 x) const {
if (x < 0) {
x += getMod();
}
if (x >= getMod()) {
x -= getMod();
}
return x;
}
constexpr i64 val() const {
return x;
}
constexpr MInt operator-() const {
MInt res;
res.x = norm(getMod() - x);
return res;
}
constexpr MInt inv() const {
return power(*this, getMod() - 2);
}
constexpr MInt &operator*=(MInt rhs) & {
if (getMod() < (1ULL << 31)) {
x = x * rhs.x % int(getMod());
} else {
x = mul(x, rhs.x, getMod());
}
return *this;
}
constexpr MInt &operator+=(MInt rhs) & {
x = norm(x + rhs.x);
return *this;
}
constexpr MInt &operator-=(MInt rhs) & {
x = norm(x - rhs.x);
return *this;
}
constexpr MInt &operator/=(MInt rhs) & {
return *this *= rhs.inv();
}
friend constexpr MInt operator*(MInt lhs, MInt rhs) {
MInt res = lhs;
res *= rhs;
return res;
}
friend constexpr MInt operator+(MInt lhs, MInt rhs) {
MInt res = lhs;
res += rhs;
return res;
}
friend constexpr MInt operator-(MInt lhs, MInt rhs) {
MInt res = lhs;
res -= rhs;
return res;
}
friend constexpr MInt operator/(MInt lhs, MInt rhs) {
MInt res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
i64 v;
is >> v;
a = MInt(v);
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
return os << a.val();
}
friend constexpr bool operator==(MInt lhs, MInt rhs) {
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MInt lhs, MInt rhs) {
return lhs.val() != rhs.val();
}
friend constexpr bool operator<(MInt lhs, MInt rhs) {
return lhs.val() < rhs.val();
}
};
constexpr int MOD[] = {998244353, 1000000007};
using Z = MInt<MOD[0]>;
//------取模机------//
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s, t;
cin >> s >> t;
int n = s.size(), m = t.size();
vector dp(n + 1, vector<Z>(n + 1));
s = " " + s, t = " " + t;
for (int i = 1; i <= n; i ++) {
if (i > m || s[1] == t[i]) {
dp[i][i] = 2;
}
}
for (int len = 2; len <= n; len ++) {
for (int i = 1; i + len - 1 <= n; i ++) {
int j = i + len - 1;
if (i > m || s[len] == t[i]) {
dp[i][j] += dp[i + 1][j];
}
if (j > m || s[len] == t[j]) {
dp[i][j] += dp[i][j - 1];
}
}
}
Z ans = 0;
for (int i = m; i <= n; i ++) {
ans += dp[1][i];
}
cout << ans << "\n";
return 0;
}

本文作者:Ke_scholar

本文链接:https://www.cnblogs.com/Kescholar/p/18706506

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Ke_scholar  阅读(6)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起