图片出自:华为机试真题 Java 实现【优选核酸检测点】【2022.11 Q4 新题】_寻找核酸检测点java_MISAYAONE的博客-CSDN博客
首先这是一道很恶心的题目。题目信息量大,逻辑分支多,还有各种细节上的坑。
本着死磕精神,耗时2h+,总算是撸完了代码(ps:时间不充裕禁入)。
结果发现和答主的代码有出入,并自认为自己的方法更合理一些,贴出代码,欢迎批评交流共同进步。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] now = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int[] finish = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int n = Integer.parseInt(sc.nextLine());
int[][] check_points = new int[n][];
for (int i=0;i<n;i++){
check_points[i] = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
}
// Queue<<id,useTime,money>>
Queue<List<Integer>> result_set = new PriorityQueue<>((a,b)->{
int ret = a.get(1) -b.get(1);
if (ret == 0){
int ret1 = a.get(2) -b.get(2);
if (ret1==0){
return a.get(0) - b.get(0);
}
return ret1;
}
return ret;
});
int now_hour = now[0];
int available_time = timeDiff(now,finish);
if(finish[0]>20){
available_time = available_time-timeDiff(new int[]{20,0},finish);
}
if (now[0]<8){
available_time = available_time-timeDiff(now,new int[]{8,0});
}
for(int i=0;i<check_points.length;i++){
int[] check_point = check_points[i];
int id = check_point[0];
int distance = check_point[1];
int peoples = check_point[2];
if (available_time<=0){
continue;
}
int useTime = 0;
if(now_hour<8){// 早于8点,从8点起算
int start_to_8 = timeDiff(now,new int[]{8,0});// 时间差值
if (10*distance <= start_to_8){//8点前到达,以下类比,不重复注释
useTime = 10*distance + peoples;//可以在8点前到达,8点到,直接取 路程耗时+排队人数
}else{//8点后到达,以下类比,不重复注释
useTime = 10*distance + (10*distance-start_to_8) * 2 + peoples;//路程耗时+增加排队人数+原有排队人数
}
}else if (now_hour<10){
int start_to_10 = timeDiff(now,new int[]{10,0});
if(10*distance<=start_to_10){
useTime = 10*distance*3 +peoples;//10点以前到达, 10*dis + 2*10*dis + peo
}else{
useTime = start_to_10*3+peoples;//10*dis + start_to*2 + peo - (10*dis-start_to)
}
}else if (now_hour < 12){
int start_to_12 = timeDiff(now,new int[]{12,0});
if (10*distance<=start_to_12){
useTime = Math.max(peoples, 10 * distance);
}else{
if(peoples<=start_to_12){//判断行程中,point原有队列是否消耗完
useTime=10*distance + 9*(10*distance-start_to_12);// 12点后,没有遗留的队友
}else{
useTime=10*distance + 9*(10*distance-start_to_12) + (peoples-start_to_12);//有遗留的队友
}
}
}else if (now_hour < 14){
int start_to_14 = timeDiff(now,new int[]{14,0});
if (10*distance<=start_to_14){
useTime=100*distance+peoples;//10*dis + 9*10*dis + peo;
}else{
useTime=10*start_to_14 +peoples;// 10*dis + 9*start_to + peo - (10*dis-start_to)
}
}else if(now_hour < 20){
useTime = Math.max(10 * distance, peoples);
}else{
continue;
}
if (useTime>available_time){
continue;
}
result_set.offer(Arrays.asList(id,useTime,10*distance));
}
System.out.println(result_set.size());
result_set.stream().map(l->l.stream().map(String::valueOf).reduce((a,b)->{return a+" "+b;}).get()).forEach(System.out::println);
}
/**
* time2-time1
* @param time1
* @param time2
* @return
*/
public static int timeDiff(int[] time1,int[] time2){
return (time2[0]-time1[0])*60 + time2[1] -time1[1];
}
相关总结:
考查信息处理能力,逻辑分析能力。本题核心在于对多时段用时变化的处理,因此如何处理时间非常重要。常见的方案有:1.统一换成以每天0点为起点的整数分钟时间(“引用答主” 用的此方案);2.针对特定情况封装相应的时间处理函数,本题中要求输出的耗时单位为分钟,但给出的时间是数组([hour,minute]),因此,简单封装了一个函数 timeDiff(int[],int[]),转换格式并输出分钟时间差。