这里写自定义目录标题
更多精彩内容
这里是带你游历编程世界的Dashcoding编程社,我是Dash/北航硕士/ICPC区域赛全国排名30+/给你呈现我们眼中的世界!
256题算法特训课,帮你斩获大厂60W年薪offer
原题
米哈游校招真题玫瑰鸭
B站动画详解
问题分析
这个问题要求计算Dash能够制作的玫瑰鸭的最大数量。每只玫瑰鸭需要两个玫瑰花和两个鸭肉。Dash手头有三种食材:玫瑰花 a a a,鸭肉 b b b,以及一种神秘的魔法食材 c c c。这个魔法食材可以作为玫瑰花或者鸭肉使用。
本问题的关键在于合理分配魔法食材 c c c。首先,我们需要看玫瑰花和鸭肉的数量是否相等。如果它们相等,那么直接考虑将魔法食材平均分配为玫瑰花和鸭肉。否则,我们需要将部分魔法食材分配给数量较少的食材,以使玫瑰花和鸭肉的数量接近。
思路分析
-
初步判断:我们先判断玫瑰花和鸭肉的数量之差 ∣ a − b ∣ |a - b| ∣a−b∣ 与魔法食材 c c c 的关系。如果 c c c 小于等于 ∣ a − b ∣ |a - b| ∣a−b∣,那么我们只能用部分魔法食材来填补玫瑰花和鸭肉的差值。此时我们可以制作的玫瑰鸭数量为 min(a, b) + c 的一半。
-
进一步处理:如果 c c c 大于 ∣ a − b ∣ |a - b| ∣a−b∣,我们首先用部分魔法食材平衡玫瑰花和鸭肉的数量,使得它们数量相等。然后,剩余的魔法食材平均分配为玫瑰花和鸭肉。此时制作的玫瑰鸭数量为 (max(a, b) + (c - |a - b|) // 2) // 2。
-
边界情况:特别注意当 a a a、 b b b 和 c c c 中某一个值较小时的情况,算法需要处理这种极端情况下的食材分配问题。
算法实现
首先判断魔法食材是否足够用来平衡玫瑰花和鸭肉的数量,然后根据不同的情况计算出最大能制作的玫瑰鸭数量。
代码详解
标准代码程序
C++代码
#include <iostream>
#include <cmath> // 用于abs函数
using namespace std;
int main() {
long long a, b, c;
cin >> a >> b >> c;
if (c <= abs(a - b)) {
// 如果魔法食材不足以平衡玫瑰花和鸭肉的差值
// 直接使用魔法食材填补少的那一方
// 最终能够制作的玫瑰鸭数量为较小的一方加上魔法食材后除以2
cout << (min(a, b) + c) / 2 << endl;
} else {
// 如果魔法食材足以平衡玫瑰花和鸭肉的差值
// 使用部分魔法食材平衡两者数量
// 然后将剩余的魔法食材平均分配给玫瑰花和鸭肉
// 最终能够制作的玫瑰鸭数量为两者数量相等后加上剩余魔法食材的一半再除以2
cout << (max(a, b) + (c - abs(a - b)) / 2) / 2 << endl;
}
return 0;
}
Java代码
import java.util.Scanner;
public class RoseDuck {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long a = scanner.nextLong();
long b = scanner.nextLong();
long c = scanner.nextLong();
if (c <= Math.abs(a - b)) {
System.out.println((Math.min(a, b) + c) / 2);
} else {
System.out.println((Math.max(a, b) + (c - Math.abs(a - b)) / 2) / 2);
}
scanner.close();
}
}
Python代码
a, b, c = map(int, input().split())
if c <= abs(a - b):
# 如果魔法食材不足以平衡玫瑰花和鸭肉的差值
# 直接使用魔法食材填补少的那一方
# 最终能够制作的玫瑰鸭数量为较小的一方加上魔法食材后除以2
print((min(a, b) + c) // 2)
else:
# 如果魔法食材足以平衡玫瑰花和鸭肉的差值
# 使用部分魔法食材平衡两者数量
# 然后将剩余的魔法食材平均分配给玫瑰花和鸭肉
# 最终能够制作的玫瑰鸭数量为两者数量相等后加上剩余魔法食材的一半再除以2
print((max(a, b) + (c - abs(a - b)) // 2) // 2)
Javascript代码
function maxRoseDucks(a, b, c) {
if (c <= Math.abs(a - b)) {
return Math.floor((Math.min(a, b) + c) / 2);
} else {
return Math.floor((Math.max(a, b) + Math.floor((c - Math.abs(a - b)) / 2)) / 2);
}
}
const input = prompt("Enter values for a, b, and c separated by space: ").split(' ');
const a = parseInt(input[0]);
const b = parseInt(input[1]);
const c = parseInt(input[2]);
console.log(maxRoseDucks(a, b, c));
复杂度分析
在这道题目中,算法的时间复杂度和空间复杂度都非常低,主要因为计算的过程只涉及到简单的数学运算,而没有使用循环、递归或复杂的数据结构。
-
时间复杂度
算法的主要部分是对输入的三个整数a、b和c进行数学运算,整个过程包括以下几步:- 计算abs(a - b):求两个数的差值并取绝对值,这是一个O(1)的操作。
- 判断c <= abs(a - b):这是一个简单的比较操作,复杂度为O(1)。
- 根据条件选择分支,并进行简单的加法、减法、除法等运算,这些操作都是O(1)。
因此,整个算法的时间复杂度为 O ( 1 ) O(1) O(1)。
- 空间复杂度
在这个算法中,除了存储输入的三个变量a、b和c之外,没有使用额外的数据结构来存储数据。所有的计算都是在常数空间内完成的。
因此,整个算法的空间复杂度为 O ( 1 ) O(1) O(1)。
总结
该算法的时间复杂度和空间复杂度均为 O ( 1 ) O(1) O(1),这是因为算法仅仅是对输入的三个变量进行几次简单的数学运算,不涉及到任何复杂的操作。这使得算法非常高效,可以在极短的时间内处理输入并得出结果,即使输入的范围达到最大值(即 1 0 9 10^9 109)。