【哈希表+优先队列】这道题说实话是不难的,用哈希表记录每个人的折扣,再用哈希表记录每种商品的名称和同名商品商品信息的优先队列,队列中按照价格排序,价格相同按照过期时间点排序。插入操作就完成了。
购买时:挨个弹出队列中的内容,如果当前商品过期,直接删除不用管了,因为题目中时间点是非递减的,过期的商品以后再也用不到了。验证商品数量num和要购买的数量number的关系,如果数量不够,就全买下,把number-num,然后还要把商品放到list中(防止最后买不了回滚),再继续弹出下一个验证。如果商品数量=要购买的数量,说明一定可以购买成功,break就行了。如果商品数量>剩余要购买的数量,说明可以购买成功,需要把当前这个商品的num设置为num-number,然后放进rem列表中。直到队列中的商品全部都被遍历过了。
如果最后number为0,说明可以购买成功,把rem中的再加回去;如果number不为0,说明不能购买成功,把list中的回滚回去。
class Goods {
public int time;
public int end;
public int num;
public int price;
public String item;
Goods(int t, int e, int n, int p, String it) {
end = e; num = n; price = p; item = it; time = t;
}
void setNum(int n) {
num = n;
}
public String toString() {
return item + "," + price + "," + end + "," + num;
}
}
class VendingMachine {
Map<String, PriorityQueue<Goods>> map = new HashMap();
Map<String, Integer> cut = new HashMap();
// PriorityQueue<Goods> queue = new PriorityQueue<Goods>((a, b) -> {
// if (a.price < b.price) return -1;
// if (a.end < b.end) return -1;
// return 1;
// });
public VendingMachine() {
}
public void addItem(int time, int number, String item, int price, int duration) {
if (!map.containsKey(item)) {
PriorityQueue<Goods> queue = new PriorityQueue<Goods>((a, b) -> {
// if (a.price == b.price) return a.end - b.end;
if (a.price < b.price) return -1;
if (a.price == b.price && a.end < b.end) return -1;
return 1;
// return a.price - b.price;
});
map.put(item, queue);
}
map.get(item).offer(new Goods(time, time + duration, number, price, item));
// System.out.println(map.get(item).size());
}
public long sell(int time, String customer, String item, int number) {
if (!cut.containsKey(customer)) {
cut.put(customer, 100);
}
int c = cut.get(customer);
if (!map.containsKey(item)) return -1;
PriorityQueue<Goods> queue = map.get(item);
double price = 0;
List<Goods> list = new ArrayList();
List<Goods> rem = new ArrayList();
// while (!queue.isEmpty()) {
// Goods goods = queue.poll();
// System.out.println(goods.toString());
// }
while (!queue.isEmpty()) {
Goods goods = queue.poll();
// System.out.println(goods.toString());
if (goods.time > time) {
continue;
}
if (goods.end < time) {
continue;
} else {
if (goods.num >= number) {
if (goods.num == number) {
price += (double)number * goods.price;
number = 0; break;
} else {
goods.setNum(goods.num - number);
price += (double)number * goods.price;
rem.add(goods);
number = 0; break;
}
} else {
list.add(goods);
price += (double)goods.num * goods.price;
number -= goods.num;
}
}
}
// System.out.println("****by******" + number + "," + price);
if (number == 0) {
cut.put(customer, Math.max(30, cut.get(customer) - 1));
for (var goods: rem) queue.offer(goods);
// for (var goods: list) queue.offer(goods);
// System.out.println(price);
return (long)((price * c + 100 - 1) / 100);
} else {
for (var goods: list) queue.offer(goods);
return -1;
}
}
}