蚂蚁金服笔试 蚂蚁金服笔试题 0828

笔试时间:2024年08月28日 秋招

历史笔试传送门:2023秋招笔试合集

第一题

题目

小苯看中了一件价值为p元的物品,他手里有1个“打折券"和1个“立减券”。两种优惠券可以都用在物品上,且使用顺序也是任意的。两种优惠券分别以整数x和y的方式给出。打折券:如果当前物品价格为p,使用后,物品价格变为:x·p/100上取整。立减券:如果当前物品价格为P,使用后,物品价格变为:max(0,p-y)。即物品价格立减y元,但最多减到0.小苯想知道,这件价值为p的物品最少可以花多少钱买到。

输入描述

输入包含一行三个正整数p,x,y(1≤p≤10^9,1≤x≤100,1≤y≤10^9),分别表示物品的价格,“打折券”和“立减券”的优惠力度。

输出描述

输出包含一行一个整数,表示最少花费。

样例输入

4 70 1

样例输出

2

说明

可以先使用打折券,价格变为4*70/100=3(向上取整),再使用立减券,价格减为2。

参考题解

要找到小苯最少能花多少钱购买这件价值为p元的物品,我们需要考虑不同的使用优惠券的顺序,并计算每种情况下的最终价格。根据描述,有两种顺序:先使用“打折券”,再使用“立减券”。先使用“立减券”,再使用“打折券”。分别计算这两种情况的结果,然后取最小值即可。先使用打折券:打折后的价格为:p1 = ceil(x * p / 100)。这里的ceil表示向上取整。再使用立减券:final_price1 = max(0, p1 - y)。先使用立减券:立减后的价格为:p2 = max(0, p - y)。再使用打折券:final_price2 = ceil(x * p2 / 100)。比较两种情况的结果:最少花费为min(final_price1, final_price2)。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <cmath>

using namespace std;

int main() {
    long long p, x, y;
    cin >> p >> x >> y;

    // 情况1: 先打折再立减
    long long p1 = (x * p + 99) / 100; // 相当于ceil(x * p / 100)
    long long final_price1 = max(0LL, p1 - y);

    // 情况2: 先立减再打折
    long long p2 = max(0LL, p - y);
    long long final_price2 = (x * p2 + 99) / 100; // 相当于ceil(x * p2 / 100)

    // 输出最少花费
    cout << min(final_price1, final_price2) << endl;

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        long p = scanner.nextLong();
        long x = scanner.nextLong();
        long y = scanner.nextLong();
        
        // 情况1: 先打折再立减
        long p1 = (x * p + 99) / 100; // 相当于ceil(x * p / 100)
        long finalPrice1 = Math.max(0, p1 - y);

        // 情况2: 先立减再打折
        long p2 = Math.max(0, p - y);
        long finalPrice2 = (x * p2 + 99) / 100; // 相当于ceil(x * p2 / 100)

        // 输出最少花费
        System.out.println(Math.min(finalPrice1, finalPrice2));
        
        scanner.close();
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

import math

# 输入
p, x, y = map(int, input().split())

# 情况1: 先打折再立减
p1 = (x * p + 99) // 100  # 相当于ceil(x * p / 100)
final_price1 = max(0, p1 - y)

# 情况2: 先立减再打折
p2 = max(0, p - y)
final_price2 = (x * p2 + 99) // 100  # 相当于ceil(x * p2 / 100)

# 输出最少花费
print(min(final_price1, final_price2))

第二题

题目

小红拿到了一个数组,她可以进行最多一次操作:选择一个元素,使其加1. 小红希望操作结束后,数组所有元素乘积的末尾有尽可能多的0。你能帮帮她吗?

输入描述

第一行输入一个正整数n,代表数组的大小。

第二行输入n个正整数ai,代表数组的元素。

1≤n≤10^5 1≤ai≤10^9

输出描述

一个整数,代表操作结束后,所有元素乘积的末尾0的数量最大值。

样例输入

4 1 2 3 4

样例输出

1

说明

将第四个元素加1即可,数组变成4,1,2,3,5,所有元素乘积为30,末尾有一个0。

参考题解

计算当前数组所有元素乘积的末尾0的数量,即统计数组中所有元素的因子2和因子5的总数,末尾0的数量就是这两个总数的最小值。对于每个元素ai,我们假设对其加1,计算其对总因子2和因子5数量的影响,并得出操作后的末尾0的数量。选择能够使末尾0数量最多的元素进行加1操作,并输出结果。

C++:[此代码未进行大量数据的测试,仅供参考]

#include <iostream>
#include <vector>

using namespace std;

// 计算一个数中包含的因子f(2或5)的数量
int factCnt(int x, int f) {
    int count = 0;
    while (x % f == 0) {
        count++;
        x /= f;
    }
    return count;
}

int main() {
    int n;
    cin >> n;
    
    vector<int> a(n);
    int total2 = 0, total5 = 0;
    
    // 计算当前数组中所有元素的因子2和因子5的总数量
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        total2 += factCnt(a[i], 2);
        total5 += factCnt(a[i], 5);
    }
    
    int max0 = min(total2, total5); // 当前末尾0的数量

    // 尝试对每个元素加1并计算新的末尾0数量
    for (int i = 0; i < n; ++i) {
        int cur2 = factCnt(a[i], 2);
        int cur5 = factCnt(a[i], 5);
        
        int new2 = factCnt(a[i] + 1, 2);
        int new5 = factCnt(a[i] + 1, 5);
        
        // 更新因子2和因子5的数量
        int new2 = total2 - cur2 + new2;
        int new5 = total5 - cur5 + new5;
        
        // 计算新的末尾0的数量
        int new0 = min(new2, new5);
        max0 = max(max0, new0);
    }
    
    // 输出最大末尾0的数量
    cout << max0 << endl;

    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

import java.util.Scanner;

public class Main {
    // 计算一个数中包含的因子f(2或5)的数量
    public static int factCnt(int x, int f) {
        int count = 0;
        while (x % f == 0) {
            count++;
            x /= f;
        }
        return count;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        
        int[] a = new int[n];
        int total2 = 0, total5 = 0;
        
        // 计算当前数组中所有元素的因子2和因子5的总数量
        for (int i = 0; i < n; ++i) {
            a[i] = scanner.nextInt();
            total2 += factCnt(a[i], 2);
            total5 += factCnt(a[i], 5);
        }
        
        int max0 = Math.min(total2, total5); // 当前末尾0的数量

        // 尝试对每个元素加1并计算新的末尾0数量
        for (int i = 0; i < n; ++i) {
            int cur2 = factCnt(a[i], 2);
            int cur5 = factCnt(a[i], 5);
            
            int new2 = factCnt(a[i

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

2024 BAT笔试合集 文章被收录于专栏

持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。

全部评论

相关推荐

想去夏威夷的小哥哥在度假:5和6才是重点
点赞 评论 收藏
分享
2 3 评论
分享
牛客网
牛客企业服务