#P1931. 第2题-小美算数
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 656
            Accepted: 37
            Difficulty: 1
            
          
          
          
                       所属公司 : 
                              美团
                                
            
                        
              时间 :2024年8月24日
                              
                      
          
 
- 
                        算法标签>贪心算法          
 
第2题-小美算数
思路:数论
几何不等式,每次+1操作要让乘积最大,就需要给最小的数+1
3a+b+c≥3abc即(3a+b+c)3≥abc
等号成立当且仅当a==b==c。因此要使乘积最大,三个数要相等,所以执行+1操作需要让更小的数+1。
假设a<b<c,操作a或操作b的增加的乘积大小为为bc、ac,而bc>ac。因此操作最小的数为最优。
代码
C++
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
    long long arr[3];
    cin >> arr[0] >> arr[1] >> arr[2];
    long long k;
    long long mod = 1e9+7;
    cin >> k;
    sort(arr, arr + 3);
    long long needed = (arr[2] - arr[0]) + (arr[2] - arr[1]);
	
	// 三者均分 
    if (k >= needed) {
        k -= needed;
        arr[0] = arr[2];
        arr[1] = arr[2];
        arr[0] += k / 3;
        arr[1] += k / 3;
        arr[2] += k / 3;
		
		// 分多余的数字 
        long long remainder = k % 3;
        if (remainder == 1) {
            arr[2] += 1;
        } else if (remainder == 2) {
            arr[1] += 1;
            arr[2] += 1;
        }
    } else {
    	// 不够,先给最小的加 
        if (k<=arr[1]-arr[0]){
        	arr[0]+=k;
		}else{// 分给两个最小的数 
            k -= arr[1]-arr[0];
			arr[0]=arr[1];
			arr[0]+=k/2+k%2;
			arr[1]+=k/2;
		}
    }
    long long result = ((arr[0] % mod) * (arr[1] % mod) % mod * (arr[2] % mod)) % mod;
    cout << result << endl;
    return 0;
}
java
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        long[] nums=new long[3];
        nums[0]=in.nextLong();
        nums[1]=in.nextLong();
        nums[2]=in.nextLong();
        long k=in.nextLong();
        int MOD =1000000007;
        Arrays.sort(nums);
        //需要加上这个,要不然塔子哥的有些测试样例过不了
        // //这里需要一开始就将原始数字取模
        // for(int i=0;i<3;i++) nums[i]%=MOD;
        long sub1=nums[1]-nums[0];
        long sub2=nums[2]-nums[1];
        double ans=0;
        if(k<sub1){
            nums[0]=(nums[0]+k)%MOD;
            //需要加上这个,要不然塔子哥的测试样例过不了
            for(int i=0;i<3;i++) nums[i]%=MOD;
            ans=nums[0]*nums[1]%MOD*nums[2]%MOD;
            System.out.print((long)ans);
            return;
        }
        nums[0]=(nums[0]+sub1)%MOD;
        k-=sub1;
        if(k/2<sub2){
            nums[0]=(nums[0]+k/2+(k%2==1?1:0))%MOD;
            nums[1]=(nums[1]+k/2)%MOD;
            //需要加上这个,要不然塔子哥的测试样例过不了
            for(int i=0;i<3;i++) nums[i]%=MOD;
            ans=nums[0]*nums[1]%MOD*nums[2]%MOD;
            System.out.print((long)ans);
            return;
        }
        
        nums[0]=(nums[0]+sub2)%MOD;
        nums[1]=(nums[1]+sub2)%MOD;
        k-=(sub2*2);
        nums[0]=(nums[0]+k/3+(k%3>=1?1:0))%MOD;
        nums[1]=(nums[1]+k/3+(k%3>=2?1:0))%MOD;
        nums[2]=(nums[2]+k/3)%MOD;
        ans=nums[0]*nums[1]%MOD*nums[2]%MOD;
        System.out.print((long)ans);
        return;   
    }
}
python
a,b,c,k = list(map(int,input().split()))
num = 10 ** 9 + 7
nums = [a,b,c]
nums.sort()
# print(nums)
# print(2 * nums[2] - nums[1] - nums[0])
# print(nums[1] - nums[0])
if 2 * nums[2] - nums[1] - nums[0] < k:
    k -=  2 * nums[2] - nums[1] -nums[0]
    temp = k // 3
    num3 = nums[2] + temp
    if k % 3 == 0:
        res = num3 ** 3
    elif k % 3 == 1:
        res = num3 * num3 * (num3 + 1)
    else:
        res = num3 * (num3 + 1)**2
    print(res % num)
elif nums[1] - nums[0] < k <= 2 * nums[2] - nums[1] - nums[0]:
    k -= nums[1] - nums[0]
    temp = k // 2
    num2 = nums[1] + temp
    if k % 2 == 0:
        res = num2 * num2 * nums[2]
    elif k % 2 == 1:
        num1 = num2 + 1
        res = num1  * num2 * nums[2]
    print(res % num)
elif k <= nums[1] - nums[0]:
    num1 = nums[0] + k
    res = num1 * nums[1] * nums[2]
    print(res % num)
    ```
        题目内容
小美有三个数字a,b,c,他每次操作可以选择一个数字将其加一,最多可以操作k次,小美想知道a×b×c的最大值是多少?
由于这个数字可能很大,因此你需要输出答案对109+7取模后的结果。
输入描述
第一行四个正整数a,b,c,k(1≤a,b,c,k≤1018)表示数字和操作次数。
输出描述
输出一个整数表示答案
样例1
输入
1 2 3 1 
输出
12
说明
对1操作一次,三个数字变成[2,2,3],乘积为12
样例2
输入
输出