很好的比赛,让我大脑宕机,比赛题目还是很友好的,适合我这种基础不怎么好的
(什么queueforces,我知道参加的人多,但是你从7号下午四点多一直system test到9点才跑到66%,想提交都不行,所以题解拖的有点晚了)
最近找到一个很好的网站,可以看codeforces中的各种数据,就在这个文章中分享一下:
Codeforces Visualizer (cfviz.netlify.app)
比赛链接:
Dashboard - Codeforces Round 964 (Div. 4) - Codeforces
题A:
题目大意解析:
输入一个两位数,求各个位数的和,
比如输入77
输出14
思路:
获得一个数字的个位数就 % 10, 获得第一位就 / 10,输入的是两位数,也不需要管其他的
代码(C++):
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int tt;
cin >> tt;
while (tt--){
int n;
cin >> n;
int res = n / 10 + n % 10;
cout << res << '\n';
}
}
代码(Python):
def main():
t = II()
res = []
for _ in range(t):
n = II()
r = n % 10 + n // 10
res.append(r)
for r in res:
print(r)
题B:
题目大意解析:
每个测试用例输入一行,一行总共4个数字
前面两个数表示第一个人的两张牌,后两个数表示第二个人的两张牌
现在比赛规则是:
两个人都随机翻开一张牌进行比大小,如果大于就获胜,如果等于就平局
一共两局,一方赢的次数大于另一方就获胜
输出第一个人赢的可能局数
思路:
这题很容易漏掉一种情况,就是1 : 0 的情况也算赢
然后暴力枚举即可,把每一种情况枚举出来,如果第一个人赢的次数严格大于第二个人
结果就加一
优化:每一种情况有两次对比的可能,所以最后只需要枚举两次就行,满足条件答案就加等于2
(比赛的时候,示例1 :0这种情况没给出来,让我wa了,我还是太菜了)
代码(C++):
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int tt;
cin >> tt;
while (tt--){
int a1, a2, b1, b2;
cin >> a1 >> a2 >> b1 >> b2;
//赢的局数
int x1 = 0, x2 = 0, res = 0;
x1 = (a1 > b1) + (a2 > b2);
x2 = (a1 < b1) + (a2 < b2);
if (x1 > x2){
res += 2;
}
x1 = (a1 > b2) + (a2 > b1);
x2 = (a1 < b2) + (a2 < b1);
if (x1 > x2){
res += 2;
}
cout << res << '\n';
}
}
代码(Python):
题C:
最近在刷洛谷,刷到一个很类似的题目,好吧也不是那么相似
P1047 [NOIP2005 普及组] 校门外的树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
标的是入门题,但是不简单
题目大意解析:
看起来挺唬人的,还弄一个图,实际说的事情很简单
每个测试第一行输入三个数字n, s, m,n表示他一天计划的个数,s表示他洗澡的时间,m表示一天的分钟数目
接下来n行输入每个所用的区间,在计划时间内是无法洗澡的
求他这一天是否有时间洗澡,就是在[0, m]这个区间内,有几个区间被占满,看是否有一段长度为s的区间
思路:
首先他这个输入不是排序好的,首先按照区间左端点排序一遍,然后枚举从0到m是否存在长度大于s即可
具体方法就是从1开始遍历区间集合,然后先用第一个左端点减0,看是否大于等于s,然后往后遍历,用下一个区间的左端点减这个区间的右端点(有点像滑动窗口?(bushi))
然后最后用m减去最后一个区间有端点。
在这个过程看查看是否有一段是大于等于s的
代码(C++):
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n, s, m;
cin >> n >> s >> m;
vector<pair<int, int>> arr(n);
for (int i = 0; i < n; i++) {
int x1, x2;
cin >> x1 >> x2;
arr[i] = {x1, x2};
}
// 对arr的第一列进行排序
sort(arr.begin(), arr.end());
int x = 0;
int cur = arr[0].first;
if (cur >= s) {
x = 1;
}
for (int i = 1; i < n; i++) {
cur = arr[i].first - arr[i - 1].second;
if (cur >= s) {
x = 1;
}
}
if (m - arr[n - 1].second >= s) {
x = 1;
}
if (x) {
cout << "YES" << '\n';
} else {
cout << "NO" << '\n';
}
}
return 0;
}
代码(Python):
def main():
t = II()
res = []
for _ in range(t):
n, s, m = MII()
arr = []
for i in range(n):
x1, x2 = MII()
arr.append([x1, x2])
#可直接对arr的第一列进行排序
arr.sort()
x = 0
cur = arr[0][0]
if cur >= s:
x = 1
for i in range(1, len(arr)):
cur = arr[i][0] - arr[i - 1][1]
if cur >= s:
x = 1
if m - arr[n - 1][1] >= s:
x = 1
if x:
res.append("YES")
else:
res.append("NO")
for r in res:
print(r)
题D:
题目大意解析:
题目意思很简单,不要想多就好了(我第一开始还想怎么dp,属于脑子抽了)
第一行输入一个字符串s
第一行输入一个字符串t
字符串s中包含?这个字符,现在可以把?变成任意一个字符,寻找是否可以让s变换成拥有t的子序列(可以不连续)
如果可以就输入YES,然后输出一个满足条件的变换后的字符串s
如果不行就输入NO
思路:
不要多想,想简单一点
进行字符串匹配就可以了
同时遍历两个字符串中的字符
如果此时字符串s和t中字符相同的,就往后遍历
如果不相同,就字符串s往后遍历
如果遍历到s中的?,就把问号变成此时字符串t中的字符
然后往后遍历
最后把多余的问号随便变成一个字母就行
(算是贪心?感觉没有严格的证明)
思想就是碰到?就直接修改即可,如果s遍历完了,t还没遍历完,那就无法满足条件
代码(C++):
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
string s;
cin >> s;
string t;
cin >> t;
int x1 = 0, x2 = 0;
while (x2 < t.length() && x1 < s.length()) {
if (s[x1] == t[x2]) {
x1++;
x2++;
} else {
if (s[x1] == '?') {
s[x1] = t[x2];
x1++;
x2++;
} else {
x1++;
}
}
}
if (x2 == t.length()) {
cout << "YES" << '\n';
for (int i = 0; i < s.length(); i++) {
if (s[i] == '?') {
s[i] = 'a';
}
}
cout << s << '\n';
} else {
cout << "NO" << '\n';
}
}
return 0;
}
代码(Python):
def main():
t = II()
res = []
for _ in range(t):
s = I()
s = list(s)
t = I()
x1, x2 = 0, 0
while x2 < len(t) and x1 < len(s):
if s[x1] == t[x2]:
x1 += 1
x2 += 1
else:
if s[x1] == "?":
s[x1] = t[x2]
x1 += 1
x2 += 1
else:
x1 += 1
if x2 == len(t):
res.append("YES")
for i in range(len(s)):
if s[i] == "?":
s[i] = "a"
res.append("".join(s))
else:
res.append("NO")
for r in res:
print(r)
题E:
题目大意解析:
输入两个数字l, r
这两个数字表示黑板上有l到r(包括l 和 r)的所有整数
操作是:
现在可以选择任意两个数x, y,擦去后在相同的位置写下 3x 和 y / 3(向上取整)
输出最小操作次数,使得所有数字为0
看题目最下面的Note就好理解了
思路:
数学题,有点没想明白,贴个c++代码
代码(C++):
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int l, r;
cin >> l >> r;
r++;
int res = 0;
int x = l;
while (x > 0) {
res += 2;
x /= 3;
}
l++;
int t = 1, i = 1, j = 3;
while (i <= r) {
int c = min(j, r) - max(i, l);
if (c >= 0){
res += c * t;
}
t++;
i *= 3;
j *= 3;
}
cout << res << '\n';
}
}
感觉这次div4很简单的,某些群聊里面也把这次比赛称作div5,但我脑子可能抽了,其实还是练少了,比如第二题wa,看了半天不知道哪里错了,最后才想起来,然后第四题,本来很简单的,我又想多了,用复杂方法写半天,基础还是有点差,训练量得再加