美团2021校招笔试-编程题(通用编程试题,第10场) -3

思路:

借助队列,分别按从左到右顺序将 当前人数为0,1,2的餐桌编号 分别 放到队列0,1,2中。

(1)男:

(1.1)情况1:队列1不为空,即存在只有一个占用的餐桌

           则将此人分配到该餐桌,此时餐桌人数为2,将餐桌放到队列2

(1.2)情况2:队列1为空,即不存在只有一人占用的餐桌

          则将此人分配到无人占用的餐桌,此时餐桌热人数为1,将餐桌放到队列1

(2)女:

(2.1)情况1:队列0不为空,即存在无人占用的餐桌

            将此人分配到该餐桌,此时餐桌人数为1,将餐桌放到队列1

(2.2)情况2:队列0为空,即不存在无人占用的餐桌

            将此人分配到一人占用的餐桌,此时餐桌人数为2,将餐桌放到队列2

注:

时间复杂度:O(MLogN)

输入输出用BufferedReader和BufferedWriter才能过,用System.out.println会超时。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;

public class Main {
	public static void main(String args[]) throws NumberFormatException, IOException {
		
		BufferedReader read = new BufferedReader(new InputStreamReader(System.in));//输入
		BufferedWriter write = new BufferedWriter(new OutputStreamWriter(System.out));//输出
		
		int t = Integer.parseInt(read.readLine());//数据组数
		
		for(int i=0;i<t;i++) {//处理当前组的数据
			
			//1.数据的输入
			int n = Integer.parseInt(read.readLine());//总参桌数
			String table = read.readLine(); //当前餐桌的占用情况
			int m = Integer.parseInt(read.readLine());//当前排队的人数
			String sex = read.readLine();//当前排队的性别
			
			//2.获取当前组的就餐方案
			int[] res = getRes(table,sex);
			
			//3.输出方案
			for(int r:res) {
				write.write(Integer.toString(r));
				write.newLine();//换行
			}
		}
		write.flush();
		
	}

	/*
	 * 获取当前组的就餐方式
	 * 
	 * table:当前餐桌的占用情况
	 * sex: 当前排队的性别
	 * */
	private static int[] getRes(String table, String sex) {
		List<PriorityQueue<Integer>> Q = new ArrayList<PriorityQueue<Integer>>();//列表Q中的元素类型是队列。
		//1.列表Q中包含三个优先队列,分别按从左到右的顺序,对应当前餐桌的占用情况:0,1,2
		Q.add(new PriorityQueue<Integer>());
		Q.add(new PriorityQueue<Integer>());
		Q.add(new PriorityQueue<Integer>());
		
		//2.根据当前的占用情况,分别将占用人数为0,1,2的餐桌号放到优先队列0,1,2中
		for(int i=0;i<table.length();i++) {
			Q.get(table.charAt(i)-'0').add(i);//即餐桌i当前有table.charAt(i)人,其编号为i
		}
		
		//3.遍历排队队列,根据性别分配餐桌
		int[] res = new int[sex.length()];//存放分配方案
		for(int i=0;i<sex.length();i++) {
			int tnum;//存放排队队列中i所分配的餐桌编号
			
			if(sex.charAt(i)=='M') {//3.1 男
				//3.1.1 查找1个人的餐桌
				if(!Q.get(1).isEmpty()) {//存在一个人的餐桌。分配后此餐桌有2人,将其放到队列2中
					tnum=Q.get(1).poll();//最左边一个人的餐桌号
					Q.get(2).add(tnum);
				}else {//3.1.2 不存在一个人的餐桌,则将其分配到空桌。分配后,此餐桌有1人,将其放到队列1中
					tnum = Q.get(0).poll();
					Q.get(1).add(tnum);
				}
			}else {//3.2女
				//3.2.1 查找空桌
				if(!Q.get(0).isEmpty()) {//存在空桌
					tnum = Q.get(0).poll();
					Q.get(1).add(tnum);
				}else {//不存在空桌
					tnum = Q.get(1).poll();
					Q.get(2).add(tnum);
				}
				
			}
			
			//3.3 将当前的分配结果放到res。编号从1开始
			res[i]=tnum+1;
		}//for
		return res;
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值