前言:
觉得这个比赛很有意思的,都是暴力题,涉及一些细节,难度比较适合刚学编程语言的,可以很好的锻炼基础还有手速,最后两题也是比较有意思,之后也准备更新atc的比赛题解和洛谷的一些高质量比赛题解(算法网瘾就是想参加各种比赛)
如果觉得有帮助,或者觉得我写的好,可以点个赞或关注,也可以看看我的一些其他文章,我之后也会更新一些基础算法详细解释
比赛链接:
【LGR-196-Div.4】洛谷入门赛 #26 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
目录
题A:
B4017 [语言月赛 202408] 相识于 2016 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意和解题思路:
2018年8月是认识的第一个月,现在输入年和月,问认识了几个月
不需要管理月份大小的,只要月份小于8,那么表示肯定不是同一年
需要注意的是8月是第一个月,也就是7月是第0个月,减7就可以了
所以res = (x - 2016) * 12 + (y - 7)
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int x, y;
std::cin >> x >> y;
int res = (x - 2016) * 12 + (y - 8) + 1;
std::cout << res << std::endl;
}
代码(Python):
def main():
x, y = map(int, input().split())
res = (x - 2016) * 12 + (y - 7)
print(res)
题B:
B4018 [语言月赛 202408] 游戏与共同语言 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意和解题思路:
- 胜局数高者排名靠前
- 若胜局数相同,净胜数高者排名靠前
- 若净胜数仍相同,平局记录低者排名靠前
- 不存在平局记录仍相同的情况
简单的判断就行,一个一个写就不会出错了
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int wa, ca, ta, wb, cb, tb;
std::cin >> wa >> ca >> ta >> wb >> cb >> tb;
bool f = 0;
if (wa == wb) {
if (ca == cb) {
if (ta > tb) {
f = 1;
} else {
f = 0;
}
} else if (ca > cb) {
f = 1;
} else {
f = 0;
}
} else if (wa > wb) {
f = 1;
} else {
f = 0;
}
if (f) {
std::cout << "A" << std::endl;
} else {
std::cout << "B" << std::endl;
}
}
代码(Python):
def main():
wa, ca, ta = map(int, input().split())
wb, cb, tb = map(int, input().split())
f = 0
if wa == wb:
if ca == cb:
if ta > tb:
f = 1
else:
f = 0
elif ca > cb:
f = 1
else:
f = 0
elif wa > wb:
f = 1
else:
f = 0
if f == 1:
print("A")
else:
print("B")
题C:
B4019 [语言月赛 202408] 皆与生物有缘 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意和解题思路:
本题就是求两名老师评分总分的平均值,向上取整
向上取整,加上除数减一就行了,这里的除数是2,那么就在总数上加一
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, x1 = 0, x2 = 0;
std::cin >> n;
int x;
for (int i = 0; i < n; i++) {
std::cin >> x;
x1 += x;
}
for (int i = 0; i < n; i++) {
std::cin >> x;
x2 += x;
}
int res = (x1 + x2 + 1) / 2;
std::cout << res << std::endl;
}
代码(Python):
def main():
n = int(input())
a1 = list(map(int, input().split()))
a2 = list(map(int, input().split()))
res = (sum(a1) + sum(a2) + 1) // 2
print(res)
题D:
B4020 [语言月赛 202408] 两座城市的 543 千米 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意和解题思路:
果一列高铁先经过 a,再经过 b,则称其为一列由 a 市直达 b 市的高铁。
现在,给出所有高铁列车的信息,请问一共有多少列由 a 市直达 b 市的高铁
输入的第一行为四个整数 N,M,a,b。
接下来 M 行,每行的第一个整数为 l,接下来输入 l 个数
保证同一次高铁不会重复停靠某座城市
这题的意思就是找一列数字中,是否先出现a,然后出现b,定义一个bool变量f然后遍历数组就行了,然后找到a,就把f变成1,继续遍历,当f == 1且找到b的时候,那么这个就是符合条件的
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, m, a, b;
std::cin >> n >> m >> a >> b;
int res = 0;
for (int i = 0; i < m; i++) {
int len;
std::cin >> len;
bool f = 0;
for (int j = 0; j < len; j++) {
int x;
std::cin >> x;
if (x == a) {
f = 1;
}
if (f == 1 && x == b) {
res += 1;
}
}
}
std::cout << res << std::endl;
}
代码(Python):
def main():
n, m, a, b = map(int, input().split())
res = 0
for _ in range(m):
arr = list(map(int, input().split()))
f = 0
for i in range(1, len(arr)):
x = arr[i]
if x == a:
f = 1
if f == 1 and x == b:
res += 1
print(res)
题E:
B4021 [语言月赛 202408] 于抑郁中支持 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意和解题思路:
那是一段混沌的时期,风的记忆裂变为 n 块碎片,第 i 块的特征值为 ai。
定义整数 x 的后 p 位的值为 x mod 10^p。特征值后 t 位相同的记忆碎片,从属于同一事件。
请问,n 块碎片共从属于多少不同的事件
这题就是阅读理解吧,特征值后t位,那就是 x mod 10 ^ t
把每一个数字x 的x mod 10 ^ t 求出来,然后看有哪些不同
可以把求出来的值放入一个set(),最后输出这个set的长度就行了
t <= 4 ,10 ^ 4也不需要用long long
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, t;
std::cin >> n >> t;
int mod = std::pow(10, t);
std::unordered_set<int> has;
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
int a = x % mod;
has.insert(a);
}
std::cout << has.size() << std::endl;
}
代码(Python):
def main():
n, t = map(int, input().split())
mod = 10 ** t
arr = list(map(int, input().split()))
has = set()
for i in range(len(arr)):
a = arr[i] % mod
has.add(a)
print(len(has))
题F:
B4022 [语言月赛 202408] 蓝色的网易云 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意和解题思路:
风的歌单中共有 n 首歌,这些歌曲可以根据题材分为 m 类,第 i 首歌的题材为 ci。风聆并不偏好任何一种题材,因此歌单中各题材的歌曲数量相同。
现在,请你给出一个歌曲播放顺序,使得相邻播放的歌曲题材不相同。
就是说数字表示这首歌的题材,现在需要一个播放的顺序,保证相邻的题材不同
然后歌单中各种题材的歌曲数量相同,这个条件很关键,如果没有这个条件那就是比较复杂的贪心了
歌单中各种题材的歌曲数量相同,那么对于每一种歌曲,取一首歌,排成一列,然后同样的方式把歌曲取完就行
比如题目中的示例:
1 1 2 2 3 3 先取1 2 3 排列, 然后再取1 2 3 ,最后的排列就是1 2 3 1 2 3
注意题目中输出的是歌曲的编号,而且是从1开始
可以定义一个m行的二维数组,每一行都表示一种歌曲题材
然后把歌曲存储进去,输出的时候就是每一列取一个数字输出即可
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, m;
std::cin >> n >> m;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
std::vector<std::vector<int>> b(m, std::vector<int>());
for (int i = 0; i < n; i++) {
b[a[i] - 1].push_back(i + 1);
}
//遍历列,由于歌单中各种题材的歌曲数量相同,那么一个题材歌曲数量就是n / m
for (int i = 0; i < n / m; i++) {
//遍历行
for (int j = 0; j < m; j++) {
std::cout << b[j][i] << std::endl;
}
}
}
代码(Python):
def main():
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = [[] for _ in range(m)]
for i in range(n):
b[a[i] - 1].append(i + 1)
for i in range(n // m):
for j in range(m):
print(b[j][i])
题G:
B4023 [语言月赛 202408] 因友情而终结 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
好恶心的字符串题目
题目大意和解题思路:
字符串 S 是一个仅由英文小写字母构成的串。现在,你可以对字符串 S 执行任意次如下操作:
- 选择 S 长度为 4 的一个子串,将其替换为
love
。
请问,至少操作多少次,字符串 S 不再有子串 friend
。
定义:子串指的是一个字符串中连续的一段字符序列。例如,字符串
aabbcc
有子串aab
、aabb
,但abc
不是字符串aabbcc
的子串,因为其不连续。
开始我没想太多,觉得friend的数量就是答案
但其实不是,如果两个"friend"字符之间的距离小于3,那一个love就可以消除两个friend
从字符d开始替换成love即可
比如friendaafriend - > frienloveriend
我直接kmp
10^6的数据量,肯定不能直接替换的,可以先找出每个friend的起始位置,把位置放在一个数组中
然后遍历这个数组
看两个位置之间相差是否小于9,如果不小于9,那么这两个字符串就只需要一次操作就可以完成
具体看代码(有简单注释)
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::string s;
std::cin >> s;
//存放位置的数组
std::vector<int> pos;
std::string target = "friend";
int p = s.find(target);
//当找不到的时候跳出循环
while (p != std::string::npos) {
pos.push_back(p);
//从此位置后6位再开始找
p = s.find(target, p + 6);
}
int res = 0;
//循环
for (int i = 0; i < pos.size(); i++) {
res++;
//上一个位置
int last = pos[i];
//如果两个位置直接相差小于9,那么表示这两个friend可以一个love替换
//然后i++,表示跳过下一个循环
while (i + 1 < pos.size() && pos[i + 1] < last + 9) {
i++;
}
}
std::cout << res << std::endl;
}
代码(Python):
def main():
s = input()
#存放位置的数组
pos = []
target = "friend"
p = s.find(target)
#当找不到的时候跳出循环
while p != -1:
pos.append(p)
#从此位置后6位再开始找
p = s.find(target, p + 6)
res, i = 0, 0
while i < len(pos):
res += 1
#上一个位置
last = pos[i]
#如果两个位置直接相差小于9,那么表示这两个friend可以一个love替换
#然后i++,表示跳过下一个循环
while i + 1 < len(pos) and pos[i + 1] < last + 9:
i += 1
i += 1
print(res)
题H:
B4024 [语言月赛 202408] 保持连接的方式 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这题我说实话,就是烦人,没啥技巧,模拟就行了
题目大意和解题思路:
就是一个盒子,有m * n 个格子,每个格子最多只能放k个日记
然后每天写的日记放在某一格(从1开始计数)
如果这个格子满了,就取出最早放进去的日记销毁,然后输出此时销毁的日记编号和移动的日记数目
如果没满,就输出-1
比如示例:
输入
2 2 3 5 3 1 1 4 1 1 2 1 1 5 1 1 1 1 1
输出
-1 -1 -1 2 0 3 2
k为3,一个格子最多放3个,3进入(1, 1),4进入(1, 1), 2进入(1, 1)都不会满,输出-1
然后5进入满了,此时(1, 1)中编号最小的是2,需要移动0次,输出(2, 0)
1进入,移除3,需要移动2个
直接用一个哈希表模拟就行了
当哈希表此时的键对应的值小于k的时候,就输出-1
大于k的时候,就在里面找最小值的下标即可,输出下标
注意输入进来的x,y需要减一的操作
代码(C++):
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, m, k, t;
std::cin >> n >> m >> k >> t;
std::map<std::pair<int, int>, std::vector<int>> has;
for (int i = 0; i < t; i++) {
int a, x, y;
std::cin >> a >> x >> y;
x--; y--;
auto key = std::make_pair(x, y);
if (has[key].size() < k) {
has[key].push_back(a);
std::cout << -1 << std::endl;
} else {
int mn = *std::min_element(has[key].begin(), has[key].end());
auto it = std::find(has[key].begin(), has[key].end(), mn);
int move = has[key].size() - (it - has[key].begin()) - 1;
has[key].erase(it);
has[key].push_back(a);
std::cout << mn << " " << move << std::endl;
}
}
return 0;
}
代码(Python):
def main():
n, m, k, t = map(int, input().split())
has = defaultdict(list)
res = []
for _ in range(t):
a, x, y = map(int, input().split())
x -= 1
y -= 1
if len(has[(x, y)]) < k:
has[(x, y)].append(a)
res.append(-1)
else:
mn = min(has[(x, y)])
i = has[(x, y)].index(mn)
move = len(has[(x, y)]) - i - 1
has[(x, y)].pop(i)
has[(x, y)].append(a)
res.append(f"{mn} {move}")
print("\n".join(map(str, res)))
标签:std,26,洛谷,int,题解,代码,cin,C++,res
From: https://blog.csdn.net/2401_83669813/article/details/141275552