Hackerrank的最低平均等待时间

时间:2015-07-03 19:55:08

标签: java algorithm

可以找到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是客户订购时的时间   披萨,李是烹饪比萨饼所需的时间。输出格式

     

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

     

约束

     

1≤N≤10^ 5

     

0≤Ti≤10^ 9

     

1≤Li≤10^ 9

     

注意

     

等待时间计算为时间a之间的差异   客户订购披萨(他们进入商店的时间)和   她被送达的时间。

     

库克不知道未来的订单。

我已经在这几个小时了。

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

非常感谢任何帮助。

代码:

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;
        }

    }
}

1 个答案:

答案 0 :(得分:2)

在此代码中:

     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. 您总是会在等待订单中添加至少一个项目 - 但如果当前披萨在烤箱中时没有人进入商店会怎么样? (例如最后的披萨)
  2. 你比较pizzaCookTime - 例如十分钟,使用entryTime,例如下午4点。这看起来不对 - 你不应该把披萨完成的时间和entryTime进行比较吗?