24届-团子(改编题)-第二套
💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历
👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸
✨ 合集传送们 -> 🧷学长刷题笔记
🍒 本专栏已收集
140+
套题 🍄 题面描述等均已改编,如果和你实际看到的题面描述不一样请理解,做法和题目本质基本不变。🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力 💞
⚽️ 01.K小姐的植物浇水
问题描述
K小姐有一盆植物,她希望能够在最短的时间内让植物长到至少 厘米高。目前植物的高度为
厘米。
每天,K小姐可以选择以下两种浇水方式之一:
- 浇
毫升的水,植物高度增加
厘米。
- 浇
毫升的水,植物高度增加
厘米。需要注意的是,使用第二种浇水方式后,必须至少等待两天才能再次使用该方式。
请你帮助K小姐计算出让植物长到至少 厘米高所需的最少天数。
输入格式
输入一行,包含三个整数 、
和
,分别表示两种浇水方式的水量以及目标植物高度。
输出格式
输出一个整数,表示让植物长到至少 厘米高所需的最少天数。
样例输入
1 2 10
样例输出
6
数据范围
题解
本题可以使用二分查找的思想来解决。我们可以二分枚举所需的天数 ,判断在
天内是否能够让植物长到至少
厘米高。
对于每个枚举的天数 ,我们可以计算出在这
天内使用第二种浇水方式的最大次数为
。然后,我们可以计算出在这
天内,使用第一种浇水方式的次数为
。
因此,在 天内,植物的最大高度为:
如果 ,说明在
天内可以让植物长到至少
厘米高,我们可以缩小二分的范围;否则,我们需要增大二分的范围。
通过二分查找,我们可以找到最小的满足条件的天数。
时间复杂度:,其中
为目标植物高度。 空间复杂度:
。
参考代码
- Python
def is_feasible(d, x, y, z):
num = (d // 3) * y + d * x
if d % 3 != 0:
num += y
return num >= z
x, y, z = map(int, input().split())
left, right = 0, z // x + 1
while left < right:
mid = (left + right) // 2
if is_feasible(mid, x, y, z):
right = mid
else:
left = mid + 1
print(right)
- Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int x = scanner.nextInt();
int y = scanner.nextInt();
int z = scanner.nextInt();
int left = 0, right = z / x + 1;
while (left < right) {
int mid = (left + right) / 2;
if (isFeasible(mid, x, y, z)) {
right = mid;
} else {
left = mid + 1;
}
}
System.out.println(right);
}
public static boolean isFeasible(int d, int x, int y, int z) {
long num = (d / 3) * y + d * x;
if (d % 3 != 0) {
num += y;
}
return num >= z;
}
}
- Cpp
#include <iostream>
using namespace std;
int x, y, z;
bool isFeasible(int d) {
long long int num = (d / 3) * y + d * x;
if (d % 3) {
num += y;
}
return num >= z;
}
int main() {
cin >> x >> y >> z;
int left = 0, right = z / x + 1;
while (left < right) {
int mid = (left + right) / 2;
if (isFeasible(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
cout << right;
return 0;
}
🥬 02.LYA 的公寓租金分摊
问题描述
LYA 是一位年轻有为的创业者,她在城市里拥有 栋公寓楼。每栋公寓楼都有若干名租户入住,LYA 自己也在每栋楼里保留了一个住处。现在,是每个月向租户们收取租金的时候了。
对于第 栋公寓楼,共有
名租户(包括 LYA 自己),月租总金额为
。为了公平起见,LYA 决定将总租金
平均分摊给所有租户(包括她自己),每人需支付
的金额。这里,
表示对实数
向上取整。
现在,LYA 希望你能帮她计算每位租户需要支付的租金金额。
输入格式
第一行包含两个正整数 和
,分别表示 LYA 拥有的公寓楼数量和城市中租户的总数。
接下来有 行,每两行描述一栋公寓楼的信息:
- 第一行包含两个整数
和
,分别表示该公寓楼的租户总数(包括 LYA)和月租总金额。
- 第二行包含
个整数,表示每位租户(不包括 LYA)的编号。租户编号在
到
之间。
输出格式
输出包含 个整数,第
个整数表示编号为
的租户需要支付的租金金额。
样例输入
2 3
3 10
1 2
4 10
1 2 3
样例输出
7 7 3
数据范围
- 租户编号在
到
之间
题解
本题要求我们计算每位租户需要支付的租金金额。由于 LYA 自己也算作一名租户,因此每栋公寓楼的实际租户数为输入的 。
我们可以先创建一个长度为 的数组
rent
,用于存储每位租户的租金金额,初始值都为 。
然后,对于每栋公寓楼,我们计算出每位租户需要支付的租金金额 ,然后将其累加到对应租户的租金金额上。
最后,我们将 rent
数组中的租金金额按顺序输出即可。
时间复杂度为 ,其中
为每栋公寓楼的平均租户数。空间复杂度为
。
参考代码
- Python
n, m = map(int, input().split())
rent = [0] * m
for _ in range(n):
k, c = map(int, input().split())
cost = (c + k - 1) // k
for x in map(int, input().split()):
rent[x - 1] += cost
print(*rent)
- Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] nm = br.readLine().split(" ");
int n = Integer.parseInt(nm[0]);
int m = Integer.parseInt(nm[1]);
long[] rent = new long[m];
for (int i = 0; i < n; ++i) {
String[] kc = br.readLine().split(" ");
int k = Integer.parseInt(kc[0]);
int c = Integer.parseInt(kc[1]);
long cost = (c + k - 1) / k;
StringTokenizer st = new StringTokenizer(br.readLine());
while (st.hasMoreTokens()) {
int x = Integer.parseInt(st.nextToken());
rent[x - 1] += cost;
}
}
System.out.println(Arrays.stream(rent).mapToObj(Long::toString).collect(Collectors.joining(" ")));
}
}
- Cpp
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
long long rent[m] = {0};
for (int i = 0; i < n; ++i) {
int k, c;
cin >> k >> c;
long long cost = (c + k - 1) / k;
for (int j = 0; j < k - 1; ++j) {
int x;
cin >> x;
rent[x - 1] += cost;
}
}
for (int i = 0; i < m; ++i) {
cout << rent[i] << (i == m - 1 ? "\n" : " ");
}
return 0;
}
🚜 03.LYA的魔药配方
问题描述
LYA是一位天才的魔药师,她有一个包含 种材料的魔药配方。每种材料都有一个初始的魔力值
。
为了制作出更加强大的魔药,LYA可以进行最多 次魔力调整操作。每次操作如下:
- 选择两种不同的材料,设它们的下标为
和
(
)。
- 选择两个正整数
和
,满足
。
- 将第
种材料的魔力值变为
,第
种材料的魔力值变为
。
LYA想知道,在最多进行 次操作后,魔药配方中所有材料的魔力值之和最大可以达到多少。
输入格式
第一行包含两个整数 和
,分别表示魔药材料的数量和最多可以进行的操作次数。
第二行包含 个整数
,表示初始时每种材料的魔力值。
输出格式
输出一个整数,表示在最多进行 次操作后,魔药配方中所有材料的魔力值之和的最大值。
由于答案可能很大,请输出答案对 取模的结果。
样例输入
6 2
1 2 3 4 5 6
样例输出
128
数据范围
题解
本题可以使用贪心算法来解决。
为了使最后的魔力值之和最大,我们需要尽可能地将较大的魔力值调整得更大。具体策略如下:
- 将材料按照魔力值从小到大排序。
- 从最大的两个魔力值开始,将它们的乘积赋值给最大的魔力值
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏短期内不再更新,请勿继续订阅