#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
输入
输出