0
点赞
收藏
分享

微信扫一扫

电影院选座(最优位置)问题


场景描述

电影院选座位,实现每次选最优位置的逻辑。最优判断逻辑如下:位置离中心越近,位置越好(比如9*9的座位,第4排5号,比第1排1号位置更好)

 

座位实体

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Seat {
// 行偏移
private Integer x;
// 列偏移
private Integer y;
// 值越小优先级越高, 即位置越优质
private Integer priority;
}

 

电影院类

@Data
public class Cinema {
// 总行数
private int row;
// 总列数
private int column;
// 影院内最好位置(居中)偏移地址信息(key 为 x轴 和 y轴)
private Map<String, List<Integer>> offsets;
// 影院内的座位信息
private Stack<Seat> seats;

public Cinema(int row, int column) {
this.row = row;
this.column = column;

offsets = Maps.newHashMap();
seats = new Stack<>();

init();
}

/**
* 初始化影院信息
*/
private void init() {
// 1. 找到电影院内最好的座位偏移地址(包括横轴/纵轴)
List<Integer> ox = Lists.newArrayList();
ox.add((int) Math.ceil((row >> 1) + 1));
if (row % 2 == 0) {
ox.add((int) Math.ceil((row) >> 1));
}
offsets.put("rowOffset", ox);

List<Integer> oy = Lists.newArrayList();
oy.add((int) Math.ceil((column >> 1) + 1));
if (column % 2 == 0) {
oy.add((int) Math.ceil((column) >> 1));
}
offsets.put("columnOffset", oy);
System.out.println(MessageFormat.format("row=[{0}], column=[{1}]最优座位偏移信息=[{2}]", row, column, JSON.toJSONString(offsets)));


// 2. 初始化电影院座位信息
for (int i = 1; i <= row; i++) {
for (int j = 1; j <= column; j++) {
List<Integer> iox = offsets.getOrDefault("rowOffset", Lists.newArrayList());
List<Integer> ioy = offsets.getOrDefault("columnOffset", Lists.newArrayList());
int p = Math.abs(iox.get(0) - i), q = Math.abs(ioy.get(0) - j);

for (int k = 1; k < iox.size(); k++) {
int tmp = Math.abs(iox.get(k) - i);
p = Math.min(p, tmp);
}

for (int k = 1; k < ioy.size(); k++) {
int tmp = Math.abs(ioy.get(k) - j);
q = Math.min(q, tmp);
}

seats.add(new Seat(i, j, p + q));
}
}


// 3. 按照座位好坏优先级进行降序排序, 座位最好的放在栈顶
seats.sort((x, y) -> y.getPriority() - x.getPriority());

System.out.println(MessageFormat.format("row=[{0}], column=[{1}]总共初始化[{2}]个座位", row, column, seats.size()));
}


/**
* 智能预定位置(优先选择最好的座位)
*
* @param n 需要定的座位个数
* @return 返回预定的座位信息
*/
public List<Seat> choose(int n) {
List<Seat> rlt = Lists.newArrayList();
for (int i = 0; i < n; i++) {
rlt.add(seats.pop());
}
return rlt;
}

/**
* 显示当前影院座位信息
*/
public void show() {
System.out.println("当前还剩座位=" + seats.size());
System.out.println(MessageFormat.format("当前还剩[{0}]个座位, 剩余座位信息=[{1}]", seats.size(), JSON.toJSONString(seats)));
System.out.println();
}
}

 

模拟选座

public class SeatApp {

public static void main(String[] args) throws Exception {
// 初始化一个 9 * 9 的电影院
Cinema cinema = new Cinema(9, 9);
// 查看电影院座位信息
cinema.show();

// 预定三个座位
int num = 3;
List<Seat> bookSeats = cinema.choose(num);
System.out.println(MessageFormat.format("已为你选择[{0}]个座位, 座位信息=[{1}]", num, JSON.toJSONString(bookSeats)));
cinema.show();
Thread.sleep(3000);

// 再次预定五个座位
num = 5;
bookSeats = cinema.choose(num);
System.out.println(MessageFormat.format("已为你选择[{0}]个座位, 座位信息=[{1}]", num, JSON.toJSONString(bookSeats)));
cinema.show();
Thread.sleep(3000);
}

}

程序运行输出

row=[9], column=[9]最优座位偏移信息=[{"rowOffset":[5],"columnOffset":[5]}]
row=[9], column=[9]总共初始化[81]个座位
当前还剩座位=81

已为你选择[3]个座位, 座位信息=[[{"priority":0,"x":5,"y":5},{"priority":1,"x":6,"y":5},{"priority":1,"x":5,"y":6}]]
当前还剩座位=78

已为你选择[5]个座位, 座位信息=[[{"priority":1,"x":5,"y":4},{"priority":1,"x":4,"y":5},{"priority":2,"x":7,"y":5},{"priority":2,"x":6,"y":6},{"priority":2,"x":6,"y":4}]]
当前还剩座位=73


举报

相关推荐

0 条评论