zoukankan      html  css  js  c++  java
  • 【算法】公司食堂-美团2021校招笔试

    【算法】公司食堂-美团2021校招笔试

    https://www.nowcoder.com/questionTerminal/601815bea5544f389bcd20fb5ebca6a8


    1.题目


    2.我的解法(没有AC,运行超时)

    • 代码

      package 公司食堂;
      
      
      import java.io.*;
      
      /*
      根据排队人的性别,从左到右判断是否优先做这个餐桌
      遍历一轮没有优先桌,再遍历一遍选择次优
       */
      public class CompanyCanteen {
      
      
          public static void companyCanteen(int[] peopleDispose, int M, char[] sexInQueue, int[] willGo) {
              int empty = 0;//空桌
              int onePeople = 0;//一人桌
              for (int i = 0; i < M; i++) {
                  empty = 0;
                  onePeople = 0;
                  //标记空桌和一人桌
                  //涉及第几桌要+1(因为从1开始)
                  for (int j = 0; j < peopleDispose.length; j++) {
                      if (onePeople == 0 && peopleDispose[j] == 1)
                          onePeople = j + 1;
      
                      if (empty == 0 && peopleDispose[j] == 0)
                          empty = j + 1;
      
                      if (onePeople != 0 && empty != 0)
                          break;
                  }
                  //判断男性和女性的结果,更新当前餐桌的人数
                  /*
                  男性没有1人桌了,才去空桌
                  女性没有空桌了,才去一人桌
                   */
                  if (sexInQueue[i] == 'M') {
                      if (onePeople == 0) {
                          willGo[i] = empty;
                          peopleDispose[empty - 1]++;
                      } else {
                          willGo[i] = onePeople;
                          peopleDispose[onePeople - 1]++;
                      }
                  } else {
                      if (empty == 0) {
                          willGo[i] = onePeople;
                          peopleDispose[onePeople - 1]++;
                      } else {
                          willGo[i] = empty;
                          peopleDispose[empty - 1]++;
                      }
                  }
              }
          }
      
          public static void main(String[] args) throws IOException {
              BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
              BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
      
      
              int T = Integer.parseInt(reader.readLine());//数据组数
              int N;//餐桌个数
              int[] peopleDispose;//人数在餐桌上的排布
              int M;//排队人数
              char[] sexInQueue;//在排队的人的性别
              int[] willGo;//预测结果
      
              //每组数据占4行
              for (int i = 0; i < T; i++) {
                  N = Integer.parseInt(reader.readLine());
      
                  peopleDispose = new int[N];
                  String disposeStr = reader.readLine();
                  for (int j = 0; j < disposeStr.length(); j++) {
                      //字符转数字时注意Ascll码
                      peopleDispose[j] = disposeStr.charAt(j) - '0';
                  }
      
                  M = Integer.parseInt(reader.readLine());
      
                  sexInQueue = new char[M];
                  String sexInQueueStr = reader.readLine();
                  for (int j = 0; j < sexInQueueStr.length(); j++) {
                      sexInQueue[j] = sexInQueueStr.charAt(j);
                  }
      
                  willGo = new int[M];
      
                  companyCanteen(peopleDispose, M, sexInQueue, willGo);
                  for (int k = 0; k < willGo.length; k++) {
                      writer.write(Integer.toString(willGo[k]));//输出必须是String类型的
                      writer.newLine();
                  }
      
                  writer.flush();
              }
          }
      }
      

    不好在哪里

    • 时间复杂度太高,把System输入输出改用BufferedReader和BufferedWriter也超时。每次循环都要找最左边的空桌和一人桌,大可不必,可以利用数据结构使其简便。

    2.推荐解法:优先队列

    • 代码

      package 公司食堂;
      
      import java.io.*;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.PriorityQueue;
      
      /**
       * @author musecho801
       * @title CompanyCanteen1
       * @description 遍历桌号,将所有空桌、一人桌分别入队两个优先队列,
       * 根据性别判断会去哪个桌号
       * @date 2021/3/11 17:21
       */
      public class CompanyCanteen1 {
      
          public void companyCanteen(String peopleDisposeStr, int M, String sexStr, int[] rs) {
              List<PriorityQueue> list = new ArrayList<>(2);
              PriorityQueue<Integer> emptyPQ = new PriorityQueue<>();
              PriorityQueue<Integer> oneTablePQ = new PriorityQueue<>();
              list.add(emptyPQ);
              list.add(oneTablePQ);
              int k = 0;//控制rs的下标
      
              //得到空桌、一人桌 两个优先队列(默认升序)
              //i为 桌号-1
              for (int i = 0; i < peopleDisposeStr.length(); i++) {
                  if (peopleDisposeStr.charAt(i) == '0') {
                      emptyPQ.add(i);
                  } else if (peopleDisposeStr.charAt(i) == '1') {
                      oneTablePQ.add(i);
                  }
              }
      
              //根据性别判断会去哪个桌号
              for (int i = 0; i < sexStr.length(); i++) {
                  //男性:只有没有一人桌时,才选择空桌
                  if (sexStr.charAt(i) == 'M') {
                      if (oneTablePQ.peek() != null) {
                          rs[k++] = oneTablePQ.poll();
                      } else {
                          oneTablePQ.add(emptyPQ.peek());
                          rs[k++] = emptyPQ.poll();
                      }
                  } else if (sexStr.charAt(i) == 'F') {//女性:只有没有空桌时,才选择一人桌
                      if (emptyPQ.peek() != null) {
                          oneTablePQ.add(emptyPQ.peek());
                          rs[k++] = emptyPQ.poll();
                      } else {
                          rs[k++] = oneTablePQ.poll();
                      }
                  }
              }
      
              //注意:rs为去第i桌,值要+1
              for (int i = 0; i < M; i++)
                  rs[i]++;
          }
      
          public static void main(String[] args) throws IOException {
              CompanyCanteen1 cc = new CompanyCanteen1();
              BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
              BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
      
              int T = Integer.parseInt(reader.readLine());//数据组数
              for (int i = 0; i < T; i++) {
                  int N = Integer.parseInt(reader.readLine());//餐桌个数
                  String peopleDisposeStr = reader.readLine();//餐桌人数分布
                  int M = Integer.parseInt(reader.readLine());//排队人数
                  String sexStr = reader.readLine();//排队人的性别
                  int[] rs = new int[M];//结果
      
                  cc.companyCanteen(peopleDisposeStr, M, sexStr, rs);
                  for (int t : rs) {
                      writer.write(Integer.toString(t));
                      writer.newLine();
                  }
                  //flush()冲刷出流,将所有缓冲数据强制发送至目的地。不加这个,是无法输出的
                  writer.flush();
              }
      
          }
      }
      

    亮点

    • 使用优先队列直接存储所有空桌、一人桌
    • BufferedReader和BufferedWriter的运行速度较快,学会使用

    参考

    推荐算法参考:https://blog.nowcoder.net/n/933a93eea0194ebdab05bb464497a0b4

  • 相关阅读:
    js完成打印功能
    ajax的序列化表单提交
    SpringMVC学习记录
    拦截器学习记录
    SpringMVC的controller层的方法返回值
    Mybatis学习记录(3)
    Mybatis学习记录(2)
    Mybatis学习记录(1)
    02-操作系统必会问题
    01-“计算机网络”必会问题
  • 原文地址:https://www.cnblogs.com/musecho/p/14522891.html
Copyright © 2011-2022 走看看