题目:每当一位学生进入考场时,需最大化他与其他人的位置,如果多个这样的位置,安排到索引最小的位置。
分析:可将所有座位看成一条线,学生看成切分点,每个学生进入选择最长的线段中点切分。
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;
}
}