#P2345. 第1题-找出磨损度最高和最低的硬盘
-
1000ms
Tried: 71
Accepted: 33
Difficulty: 4
所属公司 :
华为
时间 :2023年12月20日-国内
-
算法标签>排序算法
第1题-找出磨损度最高和最低的硬盘
题面描述:
在一个山洞里,存在一批宝藏,其价值通过一个数组 endurances 来表示,数组中的每个元素代表宝物的价值,范围在 0 到 10000 之间,且所有值均不重复。任务是找出该数组中价值最高的三件宝物和最低的三件宝物的下标,并按照升序排列输出。输入为一个长度在 6 到 200 之间的数组,输出则包括两行,第一行为最高价值三件宝物的下标,第二行为最低价值三件宝物的下标。
思路:自定义排序
1.对[值,下标]排序,取前三大的下标和前三小的下标
2.对下标的值排序
输出
题解
在这个问题中,我们需要从一个表示宝物价值的数组中找出最高和最低的三件宝物的下标。由于数组中的值没有重复,我们可以使用优先队列(最大堆和最小堆)来高效地获取这三件宝物的下标。
具体步骤如下:
-
数据结构选择:使用两个优先队列(最大堆和最小堆)。最大堆用于存储最大的三件宝物的值和对应的下标,最小堆则用于存储最小的三件宝物的值和下标。
-
入队操作:遍历输入的宝物价值数组,将每个价值及其下标放入最大堆和最小堆中。
-
出队操作:从最大堆中取出前三个最大值的下标,并从最小堆中取出前三个最小值的下标。
-
下标排序:由于要求输出下标按升序排列,取出的下标需要进行排序。
-
输出结果:最后按要求格式输出最高和最低价值宝物的下标。
代码
python
# 从标准输入读取一行并将其转换为整数列表
a = list(map(int, input().split()))
# 创建一个包含每个元素及其下标的列表
# 这里的 a[i] 是宝物的价值,i 是其对应的下标
a = [[a[i], i] for i in range(len(a))]
# 对列表 a 进行排序,默认按第一个元素(宝物的价值)升序排序
a.sort()
# 获取价值最高的三件宝物的下标
# a[-3:] 取出最后三个元素(即最大的三个元素),然后提取它们的下标
id_mx = [i[1] for i in a[-3:]]
# 获取价值最低的三件宝物的下标
# a[:3] 取出前三个元素(即最小的三个元素),然后提取它们的下标
id_mn = [i[1] for i in a[:3]]
# 对两个下标列表进行升序排序
id_mx.sort() # 对最高价值宝物的下标进行排序
id_mn.sort() # 对最低价值宝物的下标进行排序
# 将最高价值宝物的下标以空格分隔输出
print(" ".join(map(str, id_mx)))
# 将最低价值宝物的下标以空格分隔输出
print(" ".join(map(str, id_mn)))
c++
#include <bits/stdc++.h>
using namespace std;
// 定义一个整型对,方便存储宝物的价值和下标
typedef pair<int, int> pi;
int main() {
// 最大堆用于存储最大的三个宝物的值及其下标
priority_queue<pi> q1;
// 最小堆用于存储最小的三个宝物的值及其下标
priority_queue<pi, vector<pi>, greater<pi>> q2;
int cnt = 0; // 用于记录下标
int n; // 用于存储输入的宝物价值
// 读取输入的宝物价值,直到没有更多输入
while (cin >> n) {
// 将当前价值和下标加入最大堆
q1.push({n, cnt});
// 将当前价值和下标加入最小堆
q2.push({n, cnt});
cnt++; // 下标自增
}
vector<int> ans1, ans2; // 用于存储结果下标
// 从最大堆中取出三个最大值的下标
for (int i = 0; i < 3; i++) {
auto [x1, x2] = q1.top(); // 取出最大值
q1.pop(); // 弹出最大值
ans1.push_back(x2); // 将下标存入结果数组
}
// 从最小堆中取出三个最小值的下标
for (int i = 0; i < 3; i++) {
auto [y1, y2] = q2.top(); // 取出最小值
q2.pop(); // 弹出最小值
ans2.push_back(y2); // 将下标存入结果数组
}
// 对最高价值宝物的下标进行排序
sort(ans1.begin(), ans1.end());
// 输出最高价值宝物的下标
for (auto &c : ans1)
cout << c << " ";
cout << endl; // 输出换行
// 对最低价值宝物的下标进行排序
sort(ans2.begin(), ans2.end());
// 输出最低价值宝物的下标
for (auto &c : ans2)
cout << c << " ";
return 0; // 程序结束
}
java
import java.util.*;
// 主类
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // 创建扫描器用于读取输入
List<Integer> t = new ArrayList<>(); // 用于存储输入的宝物价值
// 读取输入直到没有更多整数
while (sc.hasNextInt()) {
t.add(sc.nextInt()); // 将输入的每个整数添加到列表中
}
// 将列表转换为数组
int[] val = t.stream().mapToInt(i -> i).toArray();
// 创建最小堆,用于存储最低三件宝物的下标
PriorityQueue<Integer> min = new PriorityQueue<>((a, b) -> {
return val[a] - val[b]; // 根据宝物的价值进行排序,越小的越先出
});
// 创建最大堆,用于存储最高三件宝物的下标
PriorityQueue<Integer> max = new PriorityQueue<>((a, b) -> {
return val[b] - val[a]; // 根据宝物的价值进行排序,越大的越先出
});
// 遍历所有宝物的价值
for (int i = 0; i < val.length; i++) {
// 处理最小堆(寻找最低三件宝物)
if (min.size() < 3) {
min.add(i); // 如果堆中少于三个元素,直接添加下标
} else if (val[i] < val[min.peek()]) {
// 如果当前值比堆顶(当前最小值)小,替换堆顶
min.poll(); // 移除堆顶元素
min.add(i); // 添加当前下标
}
// 处理最大堆(寻找最高三件宝物)
if (max.size() < 3) {
max.add(i); // 如果堆中少于三个元素,直接添加下标
} else if (val[i] > val[max.peek()]) {
// 如果当前值比堆顶(当前最大值)大,替换堆顶
max.poll(); // 移除堆顶元素
max.add(i); // 添加当前下标
}
}
// 存储结果的数组
int[] amax = new int[3]; // 用于存储最高三件宝物的下标
int[] amin = new int[3]; // 用于存储最低三件宝物的下标
int k = 0;
// 从最小堆中取出最低三件宝物的下标
while (!min.isEmpty()) {
amax[k++] = min.poll(); // 依次弹出并存入数组
}
k = 0;
// 从最大堆中取出最高三件宝物的下标
while (!max.isEmpty()) {
amin[k++] = max.poll(); // 依次弹出并存入数组
}
// 对结果数组进行排序,以确保下标按升序排列
Arrays.sort(amax);
Arrays.sort(amin);
// 输出最高价值宝物的下标
for (int num : amax) System.out.print(num + " ");
System.out.println(); // 输出换行
// 输出最低价值宝物的下标
for (int num : amin) System.out.print(num + " ");
}
}
题目描述
山洞里有一批宝藏,根据各个宝物的价值给定一个数组 endurances 来表示,数组中每个元素表示宝物的价值高低( 0 到 10000 之间)。价值越大,表示重要程度越高。需要找出有这批宝藏中价值最大的三件宝物和价值最低的三件宝物的下标。
输入
一组宝物的价值数组。
说明:
(1)数组 endurances 中无重复值
(2)数组的长度范围:[6,200]
(3)数组的下标从 0 开始
输出
输出第一行为价值最高的三件宝物的下标,按下标升序展示
输出第二行为价值最低的三件宝物的下标,按下标升序展示
样例1
输入
1 50 40 68 72 86 35 14 87 99 63 75
输出
5 8 9
0 6 7
样例2
输入
23 34 56 12 11 10
输出
0 1 2
3 4 5