有华为OD考试扣扣交流群可加:948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
有N (3 <= N< 10000)
个运动员,他们的id
为0
到N-1
,他们的实力由一组整数表示。他们之间进行比赛,需要决出冠亚军。比赛的规则是0
号和1
号比赛,2
号和3
号比赛,以此类推,每一轮,相邻的运动员进行比赛,获胜的进入下一轮,实力值大的获胜,实力值相等的情况,id
小的情况下获胜;轮空的直接进入下一轮。
输入一行N
个数字代表N
个运动员的实力值(0<=实力值<=10000000000)
.
输出冠亚季军的id
,用空格隔开
2 3 4 5
3 1 2
第一轮比赛id
为0
实力值为2
的运动员和id
为1
实力值为3
的运动员比赛,1
号胜出进入下一轮争夺冠亚军。id
为2
实力值为4
的运动员和id
为3
实力值为5
的运动员比赛,3
号胜出进入下一轮争夺冠亚军。
冠亚军比赛,3
号胜1
号故冠军为3
号,亚军为1
号。
2
号与0
号,比赛进行季军的争夺,2
号实力值为4
,0
号实力值2
,故2
号胜出,得季军。
冠亚季军为3 1 2
数据量只有10000
,并不是一个很大的数据量,可以直接根据题意对比赛进行模拟。由于每一轮比赛都会使得总人数减半,大概需要logN
轮比赛,每轮比赛考虑的人数和N
相关,所以总的时间复杂度为O(NlogN)
。
比赛进行到最后的决胜轮次只会有两种情况,剩下3
个人或者4
个人。若
3
个人,假设这三个人按照id
大小排序分别为A B C
A
和B
进行比赛,胜者为冠军,败者为亚军C
轮空,直接成为季军4
个人,假设这三个人按照id
大小排序分别为A B C D
。这就是示例所给出的情况
A
和B
进行比赛,C
和D
进行比赛PS:本题的题目描述非常模糊,对于最后决胜轮次的比拼规则,只能按照唯一的示例进行猜测。
# 题目:【模拟】2023B-比赛的冠亚季军
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:模拟
# 代码看不懂的地方,请直接在群上提问
# 输入
nums = list(map(int, input().split()))
# 同时储存实力num和原编号i
nums = [(num, idx) for idx, num in enumerate(nums)]
# 进行若干次循环,退出循环的条件是nums的长度小于5
# 经过若干轮比拼之后,nums的最终长度会是3或4
while len(nums) >= 5:
# 构建一个空列表,用于储存该轮比赛的结果
nums_new = list()
# 遍历当前的nums数组,注意步长取2,表示每次取相邻的两个人进行比赛
# 前一个人为nums[i],后一个人为nums[i+1]
for i in range(0, len(nums)-1, 2):
# 如果比赛之后,前一个人的实力大于等于后一个的实力
# 则将前一个人的情况加入nums_new中
# 注意:这里之所以是≥,是因为题目要求当两个人实力相等时,认为是id小的获胜
if nums[i][0] >= nums[i+1][0]:
nums_new.append(nums[i])
# 否则将后一个人的情况加入nums_new中
else:
nums_new.append(nums[i+1])
# 如果nums的长度是奇数,说明最后一个人轮空,必须加入下一轮
if len(nums) % 2 == 1:
nums_new.append(nums[-1])
# 最后,重置nums为nums_new,用于下一个循环操作
nums = nums_new
# 经过若干轮比拼之后,nums的最终长度会是3或4,进行分类讨论
# nums的长度是3,那么A和B争夺冠亚军
# 如果B的实力强过A,那么两者位置交换
if len(nums) == 3:
if nums[1][0] > nums[0][0]:
nums[0], nums[1] = nums[1], nums[0]
print(" ".join((str(idx) for num, idx in nums)))
# nums的长度是4,那么需要先进行A和B、C和D之间的两两比较
elif len(nums) == 4:
A, B, C, D = nums
# A和B之间比较
# 若A是胜者,那么
# 将A放到nums[0]的位置,后续进行冠军争夺
# 将B放到nums[2]的位置,后续进行季军争夺
if A[0] >= B[0]:
nums[0] = A
nums[2] = B
# 若B是胜者,那么
# 将B放到nums[0]的位置,后续进行冠军争夺
# 将A放到nums[2]的位置,后续进行季军争夺
else:
nums[0] = B
nums[2] = A
# C和D之间比较
# 若C是胜者,那么
# 将C放到nums[1]的位置,后续进行冠军争夺
# 将D放到nums[3]的位置,后续进行季军争夺
if C[0] >= D[0]:
nums[1] = C
nums[3] = D
# 若D是胜者,那么
# 将D放到nums[1]的位置,后续进行冠军争夺
# 将C放到nums[3]的位置,后续进行季军争夺
else:
nums[1] = D
nums[3] = C
# 以下进行冠亚军争夺
if nums[1][0] > nums[0][0]:
nums[0], nums[1] = nums[1], nums[0]
# 以下进行季军争夺
if nums[3][0] > nums[2][0]:
nums[2], nums[3] = nums[3], nums[2]
# 输出前三名的id
print(" ".join((str(idx) for num, idx in nums[:3])))
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] input = scanner.nextLine().split(" ");
int[] nums = new int[input.length];
for (int i = 0; i < input.length; i++) {
nums[i] = Integer.parseInt(input[i]);
}
int n = nums.length;
int[] index = new int[n];
for (int i = 0; i < n; i++) {
index[i] = i;
}
int[] newNums;
while (n >= 5) {
newNums = new int[(n + 1) / 2];
for (int i = 0; i < n - 1; i += 2) {
if (nums[i] >= nums[i + 1]) {
newNums[i / 2] = nums[i];
index[i / 2] = index[i];
} else {
newNums[i / 2] = nums[i + 1];
index[i / 2] = index[i + 1];
}
}
if (n % 2 == 1) {
newNums[n / 2] = nums[n - 1];
index[n / 2] = index[n - 1];
}
nums = newNums;
n = (n + 1) / 2;
}
if (n == 3) {
if (nums[1] > nums[0]) {
int temp = nums[0];
nums[0] = nums[1];
nums[1] = temp;
temp = index[0];
index[0] = index[1];
index[1] = temp;
}
System.out.println((index[0]) + " " + (index[1]) + " " + (index[2]));
} else if (n == 4) {
int A, B, C, D;
A = nums[0];
B = nums[1];
C = nums[2];
D = nums[3];
int indexA, indexB, indexC, indexD;
indexA = index[0];
indexB = index[1];
indexC = index[2];
indexD = index[3];
if (A >= B) {
nums[0] = A;
index[0] = indexA;
nums[2] = B;
index[2] = indexB;
} else {
nums[0] = B;
index[0] = indexB;
nums[2] = A;
index[2] = indexA;
}
if (C >= D) {
nums[1] = C;
index[1] = indexC;
nums[3] = D;
index[3] = indexD;
} else {
nums[1] = D;
index[1] = indexD;
nums[3] = C;
index[3] = indexC;
}
if (nums[1] > nums[0]) {
int temp = nums[0];
nums[0] = nums[1];
nums[1] = temp;
temp = index[0];
index[0] = index[1];
index[1] = temp;
}
if (nums[3] > nums[2]) {
int temp = nums[2];
nums[2] = nums[3];
nums[3] = temp;
temp = index[2];
index[2] = index[3];
index[3] = temp;
}
System.out.println((index[0]) + " " + (index[1]) + " " + (index[2]));
}
}
}
#include
#include
#include
#include
using namespace std;
int main() {
vector<pair<int, int>> nums;
string input;
getline(cin, input);
istringstream iss(input);
int num, idx = 0;
while (iss >> num) {
nums.push_back(make_pair(num, idx));
idx++;
}
while (nums.size() >= 5) {
vector<pair<int, int>> newNums;
for (size_t i = 0; i < nums.size() - 1; i += 2) {
if (nums[i].first >= nums[i + 1].first) {
newNums.push_back(nums[i]);
} else {
newNums.push_back(nums[i + 1]);
}
}
if (nums.size() % 2 == 1) {
newNums.push_back(nums[nums.size() - 1]);
}
nums = newNums;
}
if (nums.size() == 3) {
if (nums[1].first > nums[0].first){
swap(nums[0], nums[1]);
}
for (size_t i = 0; i < 3; i++) {
cout << nums[i].second << " ";
}
cout << endl;
} else if (nums.size() == 4) {
pair<int, int> A, B, C, D;
A = nums[0];
B = nums[1];
C = nums[2];
D = nums[3];
if (A.first >= B.first) {
nums[0] = A;
nums[2] = B;
} else {
nums[0] = B;
nums[2] = A;
}
if (C.first >= D.first) {
nums[1] = C;
nums[3] = D;
} else {
nums[1] = D;
nums[3] = C;
}
if (nums[1].first > nums[0].first) {
swap(nums[0], nums[1]);
}
if (nums[3].first > nums[2].first) {
swap(nums[2], nums[3]);
}
for (size_t i = 0; i < 3; i++) {
cout << nums[i].second << " ";
}
cout << endl;
}
return 0;
}
时间复杂度:O(NlogN)
。
空间复杂度:O(N)
。
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
绿色聊天软件戳 od1336
了解更多