Educational Codeforces Round 153 (Rated for Div. 2) A-C题解
A. Not a Substring
题解
对于这个题,我们可以考虑两种可能的连续的子串:
-
有两个及以上的相同的字符,比如
(((
,()))
,那么我们就需要尽可能地构造出连续不相同的字符串,比如()()()
就非常符合我们的要求,每一对都不一样。 -
有两个及以上的不相同的字符,比如
)()(
,那么我们就可以按照上面的想法,尽可能地构造出连续相同的字符串,那么((((()))))
就是满足条件的最佳的字符串,因为它只有一对不相同的字符,而这一对是必须需要的。
所以呢,对于每个长度为n
的串s
,我们只需要构造出长度为2n
的类似()()
的串和类似(())
的串,然后判断s
是不是它们的子串,判断的方法就是使用cpp的string的find()
函数查找
代码实现
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define SZ(x) (int)(x.size())
#define FOR(i,x,y) for (int i = (x),_##i = (y);i < _##i;i++)
#define FORD(i,x,y) for (int i = (x),_##i = (y);i > _##i;i--)
inline void solve();
int main() {
ios::sync_with_stdio(false);cin.tie(nullptr);
int t = 1;
cin >> t;
FOR (id, 1, t + 1) {solve();}
return 0;
}
inline void solve() {
string s, s1 = "", s2 = "";
cin >> s;
int n = SZ(s);
FOR (i, 0, n) { // i 从 0 到 n - 1
// 构造出类似()()的字符串s1
s1 += "()";
}
FOR (i, 0, 2 * n) { // i 从 0 到 2 * n - 1,
// 构造出类似(())的字符串s2
if (i < n) {
s2 += "(";
} else {
s2 += ")";
}
}
if (s1.find(s) == s1.npos) { // 如果s不是s1的子串
cout << "YES\n";
cout << s1 << "\n";
} else if (s2.find(s) == s2.npos) { // 如果s不是s2的子串
cout << "YES\n";
cout << s2 << "\n";
} else { // 否则就是不存在了
cout << "NO\n";
}
}
B. Fancy Coins
题解
由于我们想尽可能地减少fancy coins的个数,所以需要多拿价值为k
的硬币。但是价值为1的硬币会影响我们的判断,所以我们可以先只拿必要的价值为1的硬币,必要是因为m
可能不是k
的倍数。我们想一直拿价值为k
的硬币就必须让m % k == 0
,所以必要的价值为1的硬币个数cnt = m % k
,剩余的价值为1的硬币a1-cnt
可以将它们按k
进行分组,变成价值为k的硬币。
然后我们考虑计算cnt
时产生的fancy coins的个数,如果a1 >= cnt
,那么fancy coins的个数就是0
,否则就是cnt - a1
。
接下来考虑剩下的m
,就是原始的m
减去必要的价值为1的硬币cnt
后的m
,此时m % k == 0
。这样我们只需要一直拿价值为k
的硬币(包括剩下的价值为1的硬币a1-cnt
组成的价值为k
的硬币),那么很好想的就是先减去价值为k
的regular coins,再减去价值为k
的fancy coins。
代码
#include <cassert>
#include <iostream>
using namespace std;
using ll = long long;
#define FOR(i,x,y) for (int i = (x),_##i = (y);i < _##i;i++)
inline void solve();
int main() {
ios::sync_with_stdio(false);cin.tie(nullptr);
int t = 1;
cin >> t;
FOR (id, 1, t + 1) {solve();}
return 0;
}
inline void solve() {
ll m, k, a1, ak, ans = 0; // ans记录fancy coins的总数
cin >> m >> k >> a1 >> ak;
if (m % k != 0) {
ll cnt = m % k; // 必要的价值为1的硬币
m -= cnt;
if (a1 >= cnt) { // 不需要使用价值为1的fancy coins
a1 -= cnt;
} else { // 需要使用价值为1的fancy coins
ans += cnt - a1;
a1 = 0;
}
}
assert(m % k == 0);
m -= (a1 / k) * k; // 价值为1的硬币组成的价值为k的硬币
m -= ak * k; // 价值为k的regular coins
if (m < 0) { // 不需要再使用价值为k的fancy coins
cout << ans << "\n";
} else { // 还需要使用价值为k的fancy coins
cout << ans + m / k << "\n";
}
}
C. Game on Permutation
题解
从0到n-1
中
-
对第一个lucky位置
i
来说,p[i]
只需要比0 -> i - 1
中的最小值大即可。比如说[3, 1, 2]
中值为2的位置就是lucky的。 -
对第二个及以上的lucky位置
i
来说,p[i]
需要比0 -> i - 1
中的最小值大,还需要比0 -> i - 1
的所有lucky位置对应的值小。比如说[2, 1, 4, 3]
中,4所在的位置是第一个lucky的,3所在的位置是第二个lucky的,因为3 > 1 && 3 < 4
。再比如说[2, 1, 3, 4]
中,3所在位置是第一个lucky的,而4所在的位置不是lucky的,因为4 > 3
,导致从4所在的位置可以到达3所在的位置。
代码
#include <iostream>
using namespace std;
using ll = long long;
#define FOR(i,x,y) for (int i = (x),_##i = (y);i < _##i;i++)
inline void solve();
int main() {
ios::sync_with_stdio(false);cin.tie(nullptr);
int t = 1;
cin >> t;
FOR (id, 1, t + 1) {solve();}
return 0;
}
inline void solve() {
int n, ans = 0; // ans 记录答案个数
cin >> n;
int min_lucky_value = 1e9 , min_value = 1e9; // 确保第一个lucky位置可以小于min_lucky_value
FOR(i , 0, n) { // 0 -> n - 1
int x;
cin >> x;
if (x > min_value && x < min_lucky_value) {
ans++;
min_lucky_value = x; // x < min_lucky_value, 更新最小的lucky_value
}
min_value = min(min_value, x); // 保证min_value 是0 -> i - 1的最小值
}
cout << ans << "\n";
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App