美团笔试其中一题——ABC三个数乘积最大化

题目描述

给你三个正数abc和一个k,你有k次机会,每次可以将abc其中一个加一,求k次机会后,abc乘积的最大值
例如 a b c 为 1 2 1,k为2,则最大值为222 = 8

题解

思路:贪心,每次对最小的那个数+1,因此将输入的abc进行排序,使得a<=b<=c。
朴素模拟以下情况:

  • a < b 时
  • a == b < c 时
  • a == b == c 时
#include <iostream>
#include <string>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
using Type = unsigned long long;

const Type MOD = 1e9 + 7;

void just(Type &a, Type &b, Type &c)
{
    if (a > b)
        swap(a, b);
    if (a > c)
        swap(a, c);

    if (c < b)
        swap(c, b);

    a %= MOD, b %= MOD, c %= MOD;
}

Type mymin(Type a, Type b)
{
    if (a < b)
        return a;
    else
        return b;
}

int main()
{
    Type a, b, c, k;
    cin >> a >> b >> c >> k;
    just(a, b, c);
    while (1)
    {
        if (a == b && b == c)
        {
            if (k >= 3)
            {
                Type add = k / 3;
                a += add, b += add, c += add, k -= 3 * add;
            }
            else if (k == 2)
                a++, b++, k -= 2;
            else if (k == 1)
                a++, k--;
        }
        else if (a == b)
        {
            if (k >= 2)
            {
                Type n = k / 2;
                Type cha = c - b;
                Type add = mymin(n, cha);
                a += add, b += add, k -= 2 * add;
            }
            else
                a++, k--;
        }
        else if (a < b)
        {
            Type cha = b - a;
            Type add = mymin(k, cha);
            a += add;
            k -= add;
        }

        just(a, b, c);

        if (k <= 0)
            break;
    }

    cout << ((a * b) % MOD) * c % MOD << endl;

    return 0;
}

注意事项

ab)%MOD 与 (a%MOD)(b%MOD)相等
每次对a b c 进行加法时,需要进行取余
在 最后返回 三者乘积的时候,也要取余 eg: ((a * b) % MOD) * c % MOD。否则,由于a b c k 在这个题目中是10^19次方,最后会溢出,只能pass 30%(多么痛的领悟)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值