A - 22222
点击查看代码
void solve() {std::string s;std::cin >> s;int cnt = std::count(s.begin(), s.end(), '2');std::cout << std::string(cnt, '2') << "\n";
}
B - cat
点击查看代码
void solve() {int n;std::cin >> n;std::vector<std::string> s(n);for (int i = 0; i < n; ++ i) {std::cin >> s[i];}std::sort(s.begin(), s.end(), [&](std::string & a, std::string & b) {return a.size() < b.size();});for (auto & x : s) {std::cout << x;}std::cout << "\n";
}
C - Debug
题意:给你一个字符串,把\(WA\)都改成\(AC\)。
从后往前做。
点击查看代码
void solve() {std::string s;std::cin >> s;int n = s.size();for (int i = n - 1; i ; -- i) {if (s[i - 1] == 'W' && s[i] == 'A') {s[i - 1] = 'A'; s[i] = 'C';}}std::cout << s << "\n";
}
D - Colorful Bracket Sequence
题意:有三种括号,问这个序列是否是合法的括号序列。
用栈存左括号,每次遇到右括号看栈顶的括号能不能和它匹配就行。
点击查看代码
void solve() {std::string s;std::cin >> s;std::map<char, char> mp;mp['['] = ']';mp['('] = ')';mp['<'] = '>';std::stack<char> stk;for (auto & c : s) {if (mp.count(c)) {stk.push(c);} else if (stk.empty() || mp[stk.top()] != c) {std::cout << "No\n";return;} else {stk.pop();}}if (stk.size()) {std::cout << "No\n";return;}std::cout << "Yes\n";
}
E - Palindromic Shortest Path
题意:给你一个邻接矩阵,权值为一个小写字母,求每个\(i, j\)的路径是回文串的最短路是多少。
建立一个正向图和一个反向图,把\(d[i][i] = 0\)和\(d[i][j] = 1, s[i][j] != '-'\)入队,那么\(d[i][j]\)表示从\(i\)到\(j\)的回文路径最短距离,那么它们两个一个往反图扩展,一个往正图扩展就行。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<std::string> s(n);for (int i = 0; i < n; ++ i) {std::cin >> s[i];}std::vector<std::array<std::vector<int>, 26>> adj1(n), adj2(n);for (int i = 0; i < n; ++ i) {for (int j = 0; j < n; ++ j) {if (s[i][j] != '-') {adj1[i][s[i][j] - 'a'].push_back(j);adj2[j][s[i][j] - 'a'].push_back(i);}}}std::vector d(n, std::vector<int>(n, -1));std::queue<std::pair<int, int>> q;for (int i = 0; i < n; ++ i) {d[i][i] = 0;q.push({i, i});}for (int i = 0; i < n; ++ i) {for (int j = 0; j < n; ++ j) {if (i == j) {continue;}if (s[i][j] != '-') {d[i][j] = 1;q.push({i, j});}}}while (q.size()) {auto [u, v] = q.front(); q.pop();for (int i = 0; i < 26; ++ i) {for (auto & x : adj2[u][i]) {for (auto & y : adj1[v][i]) {if (d[x][y] == -1) {d[x][y] = d[u][v] + 2;q.push({x, y});}}}}}for (int i = 0; i < n; ++ i) {for (int j = 0; j < n; ++ j) {std::cout << d[i][j] << " \n"[j == n - 1];}}
}
F - Alkane
题意:给你一棵树,要求满足每个点度数要么是1要么是4且最少有一个度数是4的节点的子图中节点数最多的。
考虑树形\(dp\),记\(f[u]\)表示以\(u\)为根的子树的最大值,那么初始\(f[u] = 1\),然后\(u\)需要选至少三个子节点,然后加上一个父节点就可以满足要求,那么选\(f\)值最大的三个子节点就行,如果子节点有四个以上,则可以直接拿最大的四个更新答案,但不要更新\(f[u]\)。然后如果有至少三个节点,那么拿三个最大的子节点加一个父节点更新答案。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<std::vector<int>> adj(n);for (int i = 1; i < n; ++ i) {int u, v;std::cin >> u >> v;-- u, -- v;adj[u].push_back(v);adj[v].push_back(u);}std::vector<int> f(n);int ans = 0;auto dfs = [&](auto self, int u, int fa) -> void {f[u] = 1;std::vector<int> a;for (auto & v : adj[u]) {if (v == fa) {continue;}self(self, v, u);a.push_back(f[v]);}std::sort(a.begin(), a.end(), std::greater<int>());if (a.size() >= 3) {f[u] = std::max(f[u], a[0] + a[1] + a[2] + 1);if (a.size() >= 4) {ans = std::max(ans, a[0] + a[1] + a[2] + a[3] + 1);}if (u != 0) {ans = std::max(ans, f[u] + 1);}}};dfs(dfs, 0, -1);if (ans == 0) {ans = -1;}std::cout << ans << "\n";
}