24届-团子(改编题)-第二套

💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历

👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸

✨ 合集传送们 -> 🧷学长刷题笔记

🍒 本专栏已收集 140+ 套题 🍄 题面描述等均已改编,如果和你实际看到的题面描述不一样请理解,做法和题目本质基本不变。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力 💞

alt

⚽️ 01.K小姐的植物浇水

问题描述

K小姐有一盆植物,她希望能够在最短的时间内让植物长到至少 厘米高。目前植物的高度为 厘米。

每天,K小姐可以选择以下两种浇水方式之一:

  1. 毫升的水,植物高度增加 厘米。
  2. 毫升的水,植物高度增加 厘米。需要注意的是,使用第二种浇水方式后,必须至少等待两天才能再次使用该方式。

请你帮助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可以进行最多 次魔力调整操作。每次操作如下:

  1. 选择两种不同的材料,设它们的下标为 )。
  2. 选择两个正整数 ,满足
  3. 将第 种材料的魔力值变为 ,第 种材料的魔力值变为

LYA想知道,在最多进行 次操作后,魔药配方中所有材料的魔力值之和最大可以达到多少。

输入格式

第一行包含两个整数 ,分别表示魔药材料的数量和最多可以进行的操作次数。

第二行包含 个整数 ,表示初始时每种材料的魔力值。

输出格式

输出一个整数,表示在最多进行 次操作后,魔药配方中所有材料的魔力值之和的最大值。

由于答案可能很大,请输出答案对 取模的结果。

样例输入

6 2
1 2 3 4 5 6

样例输出

128

数据范围

题解

本题可以使用贪心算法来解决。

为了使最后的魔力值之和最大,我们需要尽可能地将较大的魔力值调整得更大。具体策略如下:

  1. 将材料按照魔力值从小到大排序。
  2. 从最大的两个魔力值开始,将它们的乘积赋值给最大的魔力值

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

本专栏短期内不再更新,请勿继续订阅

全部评论

相关推荐

xxxxOxo:该催就催,想要你的不会因为催就挂,催了就挂的是因为本来就要挂你
点赞 评论 收藏
分享
谁知道呢_:要掉小珍珠了,库库学三年,这个结果
点赞 评论 收藏
分享
评论
2
8
分享

创作者周榜

更多
牛客网
牛客企业服务