注意: \color{red}{注意:} 注意: 个人博客传送门
A. Rapids 学说话
思路:
- 操作分为两步
- 第一步:加
Start
- 第二步:替换
GenshinImpact
- 第一步:加
- 然后模拟即可
时间复杂度: O ( n ∗ m + n ∗ k + ( n / m ) ∗ l o g ( n / m ) ) O(n * m + n * k + (n/m) * log(n/m)) O(n∗m+n∗k+(n/m)∗log(n/m))
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::string str = "GenshinImpact";
int n;
std::cin >> n;
std::string s;
std::cin >> s;
int len = str.length();
std::vector<int> p;
for (int i = 0; i + len <= n; i++) {
if (s.substr(i, len) == str) {
p.push_back(i + len);
}
}
std::sort(p.rbegin(), p.rend());
for (int i = 0; i < p.size(); i++) {
s.insert(p[i], "Start");
}
while (s.find(str) != std::string::npos) {
for (int i = 0; i + len < s.size(); i++) {
if (s.substr(i, len) == str) {
s = s.substr(0, i) + "ACM" + s.substr(i + len);
break;
}
}
}
std::cout << s << "\n";
return 0;
}
Python 解法
n = input()
s = input()
print(str.replace(s, "GenshinImpact", "ACMStart"))
B. Rapids 学跳跃
思路:
- 一定要跳到最后一个位置,所以最后一个位置一定要走。
- 可以贪心的思考,一定要去掉前
n - 1
个位置中的最大的m
个,这样使得结果一定是最小的。
时间复杂度: O ( n ) O(n) O(n)
void solve() {
int n, m;
std::cin >> n >> m;
int a[n];
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
i64 ans = a[n - 1];
std::sort(a, a + n - 1);
for (int i = 0; i + m + 1 < n; i++) {
ans += a[i];
}
std::cout << ans << "\n";
}
C. Rapids 学走路
思路:
- 前缀和板子题,如果不懂,请学习前缀和
时间复杂度: O ( n ) O(n) O(n)
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, q;
std::cin >> n >> q;
int a[n] = {};
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
i64 s[n + 1] = {0};
for (int i = 0; i < n; i++) {
s[i + 1] = s[i] + a[i];
}
while (q--) { // O(1) 查询
int l, r;
std::cin >> l >> r;
std::cout << s[r] - s[l - 1] << "\n";
}
return 0;
}
D. 图图的生存率
思路:
- 直接暴力枚举所有情况,或者用数学推理一下
- 这题赛时出现最多的就是
RE
,很多同学几乎都没考虑除0
的情况
时间复杂度: O ( 1 0 4 / 1 ) O(10^4 / 1) O(104/1)
解法一 (暴力):
void solve() {
int m, a, b;
std::cin >> m >> a >> b;
int ans = 0;
for (int i = 0; i <= 100; i++) {
for (int j = 0; j <= 100; j++) {
if (1LL * i * a + 1LL * j * b <= m) {
ans = std::max(ans, i + 2 * j + 50);
}
}
}
std::cout << std::min(std::max(ans, 75), 100) << "%\n";
}
E. chen 和 cheer 的例会之路
思路:
-
图论最短路板子题
-
跑一遍
dijkstra
即可,注意爆int
时间复杂度: O ( n 2 ) O(n^2) O(n2)
const int N = 5010;
int n, m, vis[N];
i64 mp[N][N], dist[N];
void dijstra(int u) {
memset(dist, 0x3f, sizeof dist);
dist[u] = 0;
for (int i = 0; i + 1 < n; i++) {
int t = -1;
for (int j = 1; j <= n; j++) {
if (!vis[j] && (t == -1 || dist[t] > dist[j])) {
t = j;
}
}
for (int j = 1; j <= n; j++) {
dist[j] = std::min(dist[j], dist[t] + mp[t][j]);
}
vis[t] = true;
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m;
memset(mp, 0x3f, sizeof mp);
for (int i = 0; i < m; i++) {
int u, v, w;
std::cin >> u >> v >> w;
mp[u][v] = std::min(mp[u][v], 1LL * w); // 双向边
mp[v][u] = std::min(mp[v][u], 1LL * w);
}
int s, t;
std::cin >> s >> t;
dijstra(s);
std::cout << dist[t] << "\n";
return 0;
}