【问题标题】:Hackerrank's Minimum Average Waiting TimeHackerrank 的最短平均等待时间
【发布时间】:2015-07-04 04:54:40
【问题描述】:

挑战链接见here

问题陈述

Tieu 拥有一家比萨店,他以自己的方式经营着这家餐厅。尽管 在普通的餐厅里,顾客是按照以下方式服务的 先到先得规则,Tieu 只是将平均值最小化 他的客户的等待时间。所以他可以决定为谁服务 首先,不管一个人迟早来。

不同种类的比萨饼需要不同的烹饪时间。 此外,一旦他开始做比萨饼,他就不能再做比萨饼了 直到第一个披萨完全煮熟。假设我们有三个 分别在 t=0, t=1, & t=2 时间来的顾客,以及时间 烹饪比萨饼所需的时间分别为 3、9 和 6。如果 Tieu 适用 先到先得规则,然后三人的等待时间 客户分别为 3、11 和 16。平均等待时间 这种情况是 (3 + 11 + 16) / 3 = 10。这不是优化的 解决方案。在时间 t=3 为第一个客户服务后,Tieu 可以 选择服务第三位客户。在这种情况下,等待时间 将分别为 3、7 和 17。因此平均等待时间为(3 + 7 + 17) / 3 = 9。

帮助 Tieu 达到最短平均等待时间。为了 简单,只求最小平均等待的整数部分 时间。

输入格式

第一行包含一个整数N,即数字的个数 顾客。在接下来的 N 行中,第 i 行包含两个空格 分开的数字 Ti 和 Li。 Ti 是第 i 个客户下单的时间 比萨饼,而李是煮那个比萨饼所需的时间。输出格式

显示最小平均等待时间的整数部分。

约束

1≤N≤10^5

0 ≤ Ti ≤ 10^9

1≤李≤10^9

注意

等待时间的计算是与时间的差 顾客点披萨(他们进入商店的时间)和 服务她的时间。

库克不知道未来的订单。

我已经在这里呆了几个小时了。

我很确定我的问题与我增加总等待时间的方式有关。

任何帮助将不胜感激。

代码:

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;

public class Solution {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();

        MinimumAverageWaitingTime mawt = new MinimumAverageWaitingTime();

        while(n-- > 0) mawt.insert(s.nextLong(), s.nextLong());
        System.out.print(mawt.calculateAverageWaitingTime());
    }
}

class MinimumAverageWaitingTime {
    private PriorityQueue<e_time_p_time> incomingOrders = new PriorityQueue<>(10, new Comparator<e_time_p_time>(){
        //Order by the customerWaitTime ASC
        @Override public int compare(e_time_p_time w, e_time_p_time w1) {
            return (int) (w.entryTime - w1.entryTime);
        }
    });
    private PriorityQueue<e_time_p_time> awaitingOrders = new PriorityQueue<>(10, new Comparator<e_time_p_time>(){
        //Order by the difference between entrytime and pizzaCookTime ASC
        @Override public int compare(e_time_p_time w, e_time_p_time w1) {
            return (int) (Math.abs(w.entryTime - w.pizzaCookTime) - Math.abs(w1.entryTime - w1.pizzaCookTime));
        }
    });

    private long total = 0l;

    public void insert(long customerWaitTime, long pizzaCookTime) {                
        incomingOrders.add(new e_time_p_time(customerWaitTime, pizzaCookTime));
    }

    public long calculateAverageWaitingTime() {
        int size = incomingOrders.size();

        e_time_p_time currentOrder = null;
        e_time_p_time laterOrders = null;

        while(incomingOrders.size() > 0) {
            //Start by getting the customer that has the earliest arrival time (the queue is sorted that way)
            currentOrder = incomingOrders.remove();

            //Calculate it's waiting time. 
            total += currentOrder.entryTime + currentOrder.pizzaCookTime;

            do {
                /*Move all the customers that entered the shop while the current pizza is in the oven
                  to the awaitingOrders orders queue*/
                laterOrders = incomingOrders.remove(); 
                awaitingOrders.add(laterOrders);
            } while (currentOrder.pizzaCookTime >= laterOrders.entryTime && incomingOrders.size() > 0);

            //Go through awaitingOrders queue and calculate waiting time for the remaining orders
            //(The queue is sorted as the difference between entrytime and pizzaCookTime ASC)
            while(awaitingOrders.size() > 0) {
                e_time_p_time shortestOrder = awaitingOrders.remove();
                long waitTimeBeforeCooking = Math.abs((shortestOrder.entryTime + shortestOrder.pizzaCookTime) - currentOrder.entryTime);
                total += waitTimeBeforeCooking;
            }
        }

        //It's supposed to be the average time, but first I need the total to be correct, and right now, it's not...
        System.out.println("\nTotal waiting time: ");
        return total;
    }

    private static class e_time_p_time {
        private long entryTime;
        private long pizzaCookTime;

        e_time_p_time(long entryTime, long pizzaCookTime) {
            this.entryTime = entryTime;
            this.pizzaCookTime = pizzaCookTime;
        }

    }
}

【问题讨论】:

    标签: java algorithm


    【解决方案1】:

    在这段代码中:

         do {
                /*Move all the customers that entered the shop while the current pizza is in the oven
                  to the awaitingOrders orders queue*/
                laterOrders = incomingOrders.remove(); 
                awaitingOrders.add(laterOrders);
            } while (currentOrder.pizzaCookTime >= laterOrders.entryTime && incomingOrders.size() > 0);
    

    这里有几件事看起来不对:

    1. 您总是在 awaitingOrders 中添加至少一项 - 但是如果当前披萨还在烤箱中时没有人进入商店怎么办? (例如最后一个披萨)
    2. 您比较 PizzaCookTime - 例如十分钟,输入时间,例如下午4点。这似乎不对 - 您不应该将披萨完成的时间与 entryTime 进行比较吗?

    【讨论】:

    • 对不起,彼得,我不知道发生了什么,但我发誓我看到你问了这个问题。所以这就是为什么我认为是一个延续。
    • "例如,如果我第一个到达的顾客需要 5 个小时来烹制他们的比萨饼,然后有一百个顾客需要 1 分钟。你的算法不会强迫每个人等待 5 个小时吗? "嗯,是。因为挑战表明厨师不知道特征订单。当然,除非我误会了。
    • 我错过了那行 - 是的,我认为你是对的 - 我会删除那部分
    • 但是我同意你的第一个建议。第二个我有点不确定。我有兴趣找到在当前披萨还在烤箱中时进入商店的顾客。我不会通过比较披萨完成的时间和 entryTime 来发现这一点吗?
    • 我相信 PizzaCookTime 是烹饪所需的时间 - 即比萨完成时间和比萨开始时间之间的差异。
    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 2015-03-06
    • 1970-01-01
    相关资源
    最近更新 更多