t2
package com.cytcjs.kx;
/**
* TODO
*
* @author z30048714
* @since 2023-11-17
*/
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 本题答题框内的代码仅为待实现代码,执行或提交代码时,仅包含待实现部分(含所需的import)
* CodeCheck/Cmetrics工具也仅扫描待实现部分。
* 若需要完整框架用于本地调试,请点击答题框上面的“下载完整框架代码”进行下载。
* jdk基线版本为jdk 11, 平台支持jdk 17;使用完整框架代码需满足jdk基线要求。另将于24年引入fastjson 1.2.83
* VideoService([8, 1, 1], [10, 15, 30])
* allocateChannel(3, 107, 1)
* allocateChannel(3, 108, 1)
* allocateChannel(5, 110, 1)
* queryChannel(108)
* freeChannel(13, 108)
*
* @author 命题组
* @since 2023-1-1
*/
class VideoService {
public static void main(String[] args) {
VideoService vs = new VideoService(new int[]{8, 1, 1}, new int[]{10, 15, 30});
System.out.println(vs.allocateChannel(3, 107, 1));
System.out.println(vs.allocateChannel(3, 108, 1));
System.out.println(vs.allocateChannel(5, 110, 1));
System.out.println(vs.queryChannel(108));
System.out.println(vs.freeChannel(13, 108));
}
/**
* 使用记录
*/
private Map<Integer, UseVideoLog> userLogMap = new ConcurrentHashMap<>();
/**
* 资源池
*/
private Map<String, VideoResource> resPoolMap = new ConcurrentHashMap<>();
VideoService(int[] channels, int[] charge) {
// 注册资源通道池
for (int i = 0; i < channels.length; i++) {
int num = channels[i];
int price = charge[i];
for (int j = 0; j < num; j++) {
VideoResource res = new VideoResource();
res.setResId(UUID.randomUUID().toString());
res.setPrice(price);
res.setVideoType(i);
res.setStatus(true);
resPoolMap.put(res.getResId(), res);
}
}
}
boolean allocateChannel(int time, int userId, int videoType) {
// 筛选资源
List<VideoResource> fitterResList = resPoolMap.values().stream()
.filter(c -> c.videoType >= videoType && c.status).sorted(Comparator.comparingInt(o -> o.videoType))
.collect(Collectors.toList());
VideoResource res;
if (fitterResList == null || fitterResList.size() == 0) {
// 锁定资源失败
return false;
} else {
// 成功锁定
res = fitterResList.get(0);
}
List<VideoResource> reqResPriceMappingResList = resPoolMap.values().stream()
.filter(c -> c.videoType == videoType).sorted(Comparator.comparingInt(o -> o.price))
.collect(Collectors.toList());
// 占用通道记录日志
UseVideoLog log = new UseVideoLog();
log.setUserId(userId);
log.setTime(time);
log.setActualVideoType(res.getVideoType());
log.setReqVideoType(videoType);
log.setPrice(reqResPriceMappingResList.get(0).getPrice());
log.setResId(res.getResId());
userLogMap.put(userId, log);
// 资源锁定
res.setStatus(false);
resPoolMap.put(res.getResId(), res);
return true;
}
int freeChannel(int time, int userId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return -1;
}
// 释放资源
VideoResource res = resPoolMap.get(log.getResId());
res.setStatus(true);
resPoolMap.put(log.getResId(), res);
// 移除使用记录
userLogMap.remove(userId);
// 分配给其他通道升级的用户 (按规则)
List<UseVideoLog> useVideoLogDownUserList = userLogMap.values().stream()
.filter(c -> c.getActualVideoType() > c.getReqVideoType() && c.getReqVideoType() <= res.videoType)
.sorted(Comparator.comparingInt(o -> o.userId)).collect(Collectors.toList());
// 降级匹配的用户
if (useVideoLogDownUserList != null && useVideoLogDownUserList.size() > 0) {
UseVideoLog downUser = useVideoLogDownUserList.get(0);
// 切换通道
changeChannel(time, downUser.getUserId(), res.getResId());
}
return (time - log.getTime()) * log.getPrice();
}
void changeChannel(int time, int userId, String resId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return;
}
// 占用新资源
VideoResource newRes = resPoolMap.get(resId);
newRes.setStatus(true);
resPoolMap.put(resId, newRes);
// 释放原来资源
VideoResource oldRes = resPoolMap.get(log.getResId());
oldRes.setStatus(false);
resPoolMap.put(log.getResId(), oldRes);
// 记录新资源
log.setResId(resId);
log.setActualVideoType(newRes.getVideoType());
// 分配给其他通道升级的用户 (按规则)
List<UseVideoLog> changeUserList = userLogMap.values().stream()
.filter(c -> c.getActualVideoType() > c.getReqVideoType() && c.getReqVideoType() <= oldRes.videoType)
.sorted(Comparator.comparingInt(o -> o.userId)).collect(Collectors.toList());
// 降级匹配的用户
if (changeUserList != null && changeUserList.size() > 0) {
UseVideoLog changeUser = changeUserList.get(0);
// 切换通道
changeChannel(time, changeUser.getUserId(), oldRes.getResId());
}
}
int queryChannel(int userId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return -1;
}
return log.getActualVideoType();
}
}
class UseVideoLog {
String resId;
int userId;
int time;
int reqVideoType;
int actualVideoType;
int price;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getReqVideoType() {
return reqVideoType;
}
public void setReqVideoType(int reqVideoType) {
this.reqVideoType = reqVideoType;
}
public int getActualVideoType() {
return actualVideoType;
}
public void setActualVideoType(int actualVideoType) {
this.actualVideoType = actualVideoType;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getResId() {
return resId;
}
public void setResId(String resId) {
this.resId = resId;
}
}
class VideoResource {
String resId;
int videoType;
boolean status;
int price;
public int getVideoType() {
return videoType;
}
public void setVideoType(int videoType) {
this.videoType = videoType;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getResId() {
return resId;
}
public void setResId(String resId) {
this.resId = resId;
}
}
/**
* TODO
*
* @author z30048714
* @since 2023-11-17
*/
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 本题答题框内的代码仅为待实现代码,执行或提交代码时,仅包含待实现部分(含所需的import)
* CodeCheck/Cmetrics工具也仅扫描待实现部分。
* 若需要完整框架用于本地调试,请点击答题框上面的“下载完整框架代码”进行下载。
* jdk基线版本为jdk 11, 平台支持jdk 17;使用完整框架代码需满足jdk基线要求。另将于24年引入fastjson 1.2.83
* VideoService([8, 1, 1], [10, 15, 30])
* allocateChannel(3, 107, 1)
* allocateChannel(3, 108, 1)
* allocateChannel(5, 110, 1)
* queryChannel(108)
* freeChannel(13, 108)
*
* @author 命题组
* @since 2023-1-1
*/
class VideoService {
public static void main(String[] args) {
VideoService vs = new VideoService(new int[]{8, 1, 1}, new int[]{10, 15, 30});
System.out.println(vs.allocateChannel(3, 107, 1));
System.out.println(vs.allocateChannel(3, 108, 1));
System.out.println(vs.allocateChannel(5, 110, 1));
System.out.println(vs.queryChannel(108));
System.out.println(vs.freeChannel(13, 108));
}
/**
* 使用记录
*/
private Map<Integer, UseVideoLog> userLogMap = new ConcurrentHashMap<>();
/**
* 资源池
*/
private Map<String, VideoResource> resPoolMap = new ConcurrentHashMap<>();
VideoService(int[] channels, int[] charge) {
// 注册资源通道池
for (int i = 0; i < channels.length; i++) {
int num = channels[i];
int price = charge[i];
for (int j = 0; j < num; j++) {
VideoResource res = new VideoResource();
res.setResId(UUID.randomUUID().toString());
res.setPrice(price);
res.setVideoType(i);
res.setStatus(true);
resPoolMap.put(res.getResId(), res);
}
}
}
boolean allocateChannel(int time, int userId, int videoType) {
// 筛选资源
List<VideoResource> fitterResList = resPoolMap.values().stream()
.filter(c -> c.videoType >= videoType && c.status).sorted(Comparator.comparingInt(o -> o.videoType))
.collect(Collectors.toList());
VideoResource res;
if (fitterResList == null || fitterResList.size() == 0) {
// 锁定资源失败
return false;
} else {
// 成功锁定
res = fitterResList.get(0);
}
List<VideoResource> reqResPriceMappingResList = resPoolMap.values().stream()
.filter(c -> c.videoType == videoType).sorted(Comparator.comparingInt(o -> o.price))
.collect(Collectors.toList());
// 占用通道记录日志
UseVideoLog log = new UseVideoLog();
log.setUserId(userId);
log.setTime(time);
log.setActualVideoType(res.getVideoType());
log.setReqVideoType(videoType);
log.setPrice(reqResPriceMappingResList.get(0).getPrice());
log.setResId(res.getResId());
userLogMap.put(userId, log);
// 资源锁定
res.setStatus(false);
resPoolMap.put(res.getResId(), res);
return true;
}
int freeChannel(int time, int userId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return -1;
}
// 释放资源
VideoResource res = resPoolMap.get(log.getResId());
res.setStatus(true);
resPoolMap.put(log.getResId(), res);
// 移除使用记录
userLogMap.remove(userId);
// 分配给其他通道升级的用户 (按规则)
List<UseVideoLog> useVideoLogDownUserList = userLogMap.values().stream()
.filter(c -> c.getActualVideoType() > c.getReqVideoType() && c.getReqVideoType() <= res.videoType)
.sorted(Comparator.comparingInt(o -> o.userId)).collect(Collectors.toList());
// 降级匹配的用户
if (useVideoLogDownUserList != null && useVideoLogDownUserList.size() > 0) {
UseVideoLog downUser = useVideoLogDownUserList.get(0);
// 切换通道
changeChannel(time, downUser.getUserId(), res.getResId());
}
return (time - log.getTime()) * log.getPrice();
}
void changeChannel(int time, int userId, String resId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return;
}
// 占用新资源
VideoResource newRes = resPoolMap.get(resId);
newRes.setStatus(true);
resPoolMap.put(resId, newRes);
// 释放原来资源
VideoResource oldRes = resPoolMap.get(log.getResId());
oldRes.setStatus(false);
resPoolMap.put(log.getResId(), oldRes);
// 记录新资源
log.setResId(resId);
log.setActualVideoType(newRes.getVideoType());
// 分配给其他通道升级的用户 (按规则)
List<UseVideoLog> changeUserList = userLogMap.values().stream()
.filter(c -> c.getActualVideoType() > c.getReqVideoType() && c.getReqVideoType() <= oldRes.videoType)
.sorted(Comparator.comparingInt(o -> o.userId)).collect(Collectors.toList());
// 降级匹配的用户
if (changeUserList != null && changeUserList.size() > 0) {
UseVideoLog changeUser = changeUserList.get(0);
// 切换通道
changeChannel(time, changeUser.getUserId(), oldRes.getResId());
}
}
int queryChannel(int userId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return -1;
}
return log.getActualVideoType();
}
}
class UseVideoLog {
String resId;
int userId;
int time;
int reqVideoType;
int actualVideoType;
int price;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getReqVideoType() {
return reqVideoType;
}
public void setReqVideoType(int reqVideoType) {
this.reqVideoType = reqVideoType;
}
public int getActualVideoType() {
return actualVideoType;
}
public void setActualVideoType(int actualVideoType) {
this.actualVideoType = actualVideoType;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getResId() {
return resId;
}
public void setResId(String resId) {
this.resId = resId;
}
}
class VideoResource {
String resId;
int videoType;
boolean status;
int price;
public int getVideoType() {
return videoType;
}
public void setVideoType(int videoType) {
this.videoType = videoType;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getResId() {
return resId;
}
public void setResId(String resId) {
this.resId = resId;
}
}
因为相信,所以看见.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2020-11-17 如何提高的表达(演说)能力?
2020-11-17 如何提高写作能力?
2020-11-17 20201117记 --- 管理成长修炼日志