青训营AI刷题-英雄决斗的最大胜利次数|豆包MarsCodeAI刷题

98 阅读3分钟

题目说明(python作答)

小U和小F正在进行一场由 nn 轮组成的英雄决斗比赛。在每一轮中,小U和小F各自从他们的英雄队伍中选出一位英雄进行对决,英雄的能力值将决定比赛的胜负,能力值高者获胜。小U已经按照固定的能力顺序 1,2,3,…,n1,2,3,…,n 安排了他的英雄出场顺序。

小F希望通过调整他的英雄出场顺序,最大化他的获胜轮数。请帮助小 F 确定一个最佳的出场顺序,以获得最多的胜利。

输入说明

  • number: 一个整数,表示比赛的总轮数 nn。
  • heroes: 一个长度为 nn 的正整数数组,表示小 F 的每个英雄的能力值。

输出

  • 返回一个整数,表示小 F 可以获得的最大胜利轮数

# 题目解析

这个题目是中等难度,不过所需要的知识和算法的比较简单。 通过题目描述我们可以知道小f是一个打乱的数组,同样,小U在题目中也提示我们它是一个数组,元素是1-n,题目让我们确定一个小F最佳的出场顺序的内容是一个无关紧要的条件,因为最后我们是返回小F的胜利的最大轮数。最开始看到这道题的时候,我想过用二分查找,并且结合豆包的代码提示:

def solution(number, heroes):
    # 对小F的英雄能力值进行排序
    heroes.sort()
    
    # 初始化胜利次数
    wins = 0
    
    # 从小到大遍历小U的英雄能力值
    for u_hero in range(1, number + 1):
        # 使用二分查找找到最小的且大于等于u_hero的英雄
        left, right = 0, len(heroes) - 1
        while left <= right:
            mid = (left + right) // 2
            if heroes[mid] >= u_hero:
                right = mid - 1
            else:
                left = mid + 1
        
        # 如果找到,胜利次数加1,并从heroes中移除该英雄
        if left < len(heroes):
            wins += 1
            heroes.pop(left)
    
    return wins

结果运行错误,欸奇了怪了,我又重新开始审视题目,两个半小时,我看出一些端倪,小U是一个从小到大的数组,并且小U和小F的比较每个英雄都只有一次机会,让小F数组也由小到大排序,然后一个一个比较,那么结果就是最大的胜利轮数:这是1v1的游戏,你派出最弱的,我能派出最强的吗?打完就上不了了呀,我肯定也拿最弱的,赢了我就赚了,输了也没关系,还有下一回合,我就先派出弱的,反正你也是按照弱到高排序吧,前期连胜那我就是good,前期连败我就吃利息,还是赚,好了,不废话了哈哈,上代码:

def solution(number, heroes):
# 对小F的英雄能力值进行排序
    heroes.sort()
    u_heroes = list(range(1, number + 1))


    u_pointer, f_pointer = 0, 0
    wins = 0


    while f_pointer < number and u_pointer < number:
        if heroes[f_pointer] > u_heroes[u_pointer]:
                wins += 1
                u_pointer += 1

    
        f_pointer += 1

    return wins

思路就是一个个进行比较,赢了我就加1,输了咱们就继续比较下一个,这个方法能保证win是最大次数的无论小F给什么,有多少个英雄比小U大,我们就会胜利多少次,当然我也给了for类的遍历,不过时间复杂度较高,本人实力有限,也不知道怎么优化了。如下,各位看官查收:

def solution(number, heroes):
  # 对小F的英雄能力值进行排序
  heroes.sort()
  u_heroes = list(range(1, number + 1))

  
  u_pointer, f_pointer = 0, 0
  wins = 0

  
  for f_pointer in range(number):
      for u_pointer in range(number):
  
          if heroes[f_pointer] > u_heroes[u_pointer]:
              # F's hero can win this round
              wins += 1
              u_pointer += 1
              break
      
      f_pointer += 1

  return wins

第一次发文,考虑到我们许多同学可能刚接触算法,就只用了能看的懂的线性查找,各位看官有什么问题可以一起交流哦,我陈平安很荣幸能和大家一起讨论