美团2021后端开发岗位笔试 压轴题

美团2021后端开发岗位笔试 压轴题

某公司需要抽调一批人组建 A B 两只队伍,去参加一项比赛,两只队伍的人数人别是x 和 y ,

给定 x + y 个整数,代表这 批人的技术水平,赛事租会根据计算该公司的实力水平,该公司的实力水平等于两只队伍的平均水平之和,而每只队伍的平均水平等于该队伍的所有人的水平之和除以该队伍的人数,现在需要你进行分配,这 x + y 个人,哪些人去A组,哪些人去B组,可以使得该公司的评分最高,

例如: x = 4, y = 1

员工的水平分别为: 1 2 3 4 5

则应该让 最后一名员工去B组,前4 个员工去A组,这样(1+2+3 + 4) / 4 + 5 = 7.5 总评分最高,

所有应该输出 AAAAB

输入:

4 1

1 2 3 4 5

输出:

AAAAB

import java.util.*;

public class demo01 {
  private static int x;
  private static int y;
  public static void main(String[] args) {
      Scanner scan = new Scanner(System.in);
      x = scan.nextInt();
      y = scan.nextInt();

      int[] arr = new int[x + y];
      for(int i=0;i<x+y;i++){
          arr[i] = scan.nextInt();
      }
      scan.close();

      boolean[] tag = new boolean[x+ y];

      ArrayList<ArrayList<Integer>> res = new ArrayList<>();
      Deque<Integer> path = new ArrayDeque<>();
      getAllThePossible(arr,tag,res,path);
      double[] sources = new double[res.size()];

      for(int k=0;k<res.size();k++ ){
          ArrayList<Integer> list1 = res.get(k);
          boolean[] flag = new boolean[x + y];
          for(int i : list1){
              flag[i-1] = true;
          }
          double sumA = 0,sumB = 0;
          for(int i= 0;i<x+y;i++){
              if(flag[i]){
                  sumA += arr[i];
              }else{
                  sumB += arr[i];
              }
          }
          double source = sumA / x + sumB / y ;
          sources[k] = source;
      }
      double max = 0;
      int index = 0;
      for(int i=0;i<sources.length;i++){
          if(sources[i] > max ){
              max = sources[i];
              index = i;
          }
      }
      ArrayList<Integer> last = res.get(index);
      StringBuilder sb = new StringBuilder();
      for(int i=0;i<x+y;i++){
          if(last.contains(i+1)){
              sb.append("A");
          }else{
              sb.append("B");
          }
      }
      String a = sb.toString();
      System.out.println( a);
  }

  public static void getAllThePossible( int[] arr,boolean[] tag,ArrayList<ArrayList<Integer>> res, Deque<Integer> path){
      if(path.size() == x ){
          ArrayList<Integer> temp = new ArrayList<>(path);
          Collections.sort(temp);
          if(!res.contains(temp)){
              res.add(temp);
          }
          return;
      }
      for(int i=0;i<x+y;i++){
          if(tag[i]) continue;
          path.add(arr[i]);
          tag[i] = true;
          getAllThePossible(arr,tag,res,path);
          tag[i] = false;
          path.removeLast();
      }
  }
}

总结:

这道题的难点在于逻辑比较复杂,有点混乱,但核心还是回溯算法,把所有的情况罗列出来,因为这x + y 个人要么属于 A队伍,要么属于B 队伍,所以我们只需要从x + y 个人中抽取 x 个人作为A队的,剩下的人就是B队的了,把所有的情况都罗列出来,然后逐个比较计算就可以了,

这种问题的核心在于全排列,核心算法是回溯算法。

posted @ 2020-08-23 17:41  同济小孙  阅读(496)  评论(0编辑  收藏  举报