Java笔试 - 考场座位问题

题目:每当一位学生进入考场时,需最大化他与其他人的位置,如果多个这样的位置,安排到索引最小的位置。

分析:可将所有座位看成一条线,学生看成切分点,每个学生进入选择最长的线段中点切分。

class Exam{
	//存储以p为左端点的线段
	Map<Integer,int[]> startMap;
	//存储以p为右端点的线段
	Map<Integer,int[]> endMap;
	//按顺序存储线段
	TreeSet<int[]>pq;
	int N;
	public Exam(int N){
		this.N = N;
		startMap = new HashMap<>();
		endMap = new HashMap<>();
		pq = new TreeSet<>(a,b -> {int A =  distan(a);
				int B = distan(b);
				return A-B;
				})
		addIntval(new []{-1,N});
	}
	public int removeIntv(int[] intv){
		pq.remove(intv);
		startMap.remove(intv);
		endMap.remove(intv);
	}
	public int addIntv(int[] intv){
		pq.add(intv);
		startMap.put(intv[0],intv);
		endMap.put(intv[0],intv);
	}
	public void distan(int[] b){
		return b[1] - b[0] -1;
	}
	public void leave(int p){
		int[] right = startMap.get(p);
		int[] left= endMap.get(p);
		int [] meg = new int[]{left[0],right[1]};
		removeIntv(left);
		removeIntv(right);
		addIntv(meg);
	}
	public void seat(){
		int[] longest = pq.last();
		int l = longest[0];
		int r = longest[1];
		int seat;
		if(x == -1){
			seat = 0;
		}else if(r == N){
			seat = N-1;
		}else{
			seat = (r-l)/2 + l;
		}
		int [] left = new int[]{l,seat};
		int [] right = new int[]{seat,r};
		removeIntv(longest);
		addIntv(left);
		addIntv(right);
		return seat;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值