[RocketFuel]Racer Rater

Suppose you are a fan of auto-racing and want to figure out which drivers are likely to perform well in an upcoming race. Luckily you have access to a log of the times that each racer started and finished their test race the day before.

The particular rating algorithm you have chosen is to assign each racer R a score that equals the number of other racers who both started after R started and also finished before R finished.
Note that a lower score generally suggests that the racer is faster, and this rating algorithm keeps from penalizing fast racers who have slow times simply because they are stuck behind a crash or slow racer. Additionally, this rating algorithm does not reward fast racers who pass tons of slow racers in comparison to fast racers who race when there are not many slow racers on the track to pass (compare this with rating a racer based on the net number of passes).
 
More formally, you want to write a program that will read the test race log from standard input. The first line of the log contains a single integer n from 0 to 70,000 that represents the number of racers in the log. The next n lines of the test race log have the following format:
 
racerId startTime endTime
 
where racerId is an integer in the range [0,10^9] and startTime and endTime are both integers such that 0 <= startTime < endTime <= 10^18. Each racerId will be distinct. Also, the collection of all start and end times will not contain any duplicate elements.
 
Given such an input, you should print output in the following format:
 
racerId score
 
where score is the score as defined above for racer racerId. The output lines should be sorted in ascending order ofscore with ties broken by sorting by racerId, also in ascending order. This can be accomplished with a simple sort at the end.
 
Directions:
Please code this problem in Java, C, or C++. Your solution should run in less than O(N^2) on all inputs.
Hint: The naive brute force solution is too slow to run within the time limit. You will need to think of a faster solution. Specifically, we are looking for a solution that is guaranteed to be less than O(N^2) on all inputs. One possible way to accomplish this (there are several other acceptable methods) is to use a data structure with K buckets  (e.g., K = 300), each of which is initially empty and is defined by two times. Each bucket  will eventually contain racers whose start time falls between the two times. The bucket boundaries should be chosen such that they ultimately will contain the same number of racers . Then iterate through the racers in end time order and, as you iterate over each racer, build up this bucketed data structure in such a way that you can use it to quickly count the number of racers that finished before him but started after him.
 
What We Are Looking For:
For this problem, we simply want to see that you can implement the algorithm correctly, without particular regard to principles of object orientation or modularity.  Do give us at least minimal documentation to help us understand what you are trying to accomplish in certain key places of the algorithm.
 
Sample Testcases 
input:
5
2 100 200
3 110 190
4 105 145
1 90 150
5 102 198
output:
3 0
4 0
1 1
5 2
2 3
 
Note in the above example that racer 3 has a score of 0 because no one starts after racer 3 (a drawback to this scoring system is the last racer always has a score of 0). Racer 4 also has a score of 0 because the only racer who starts after racer 4's start time (racer 3) has a later finish time. Racer 3 is listed ahead of racer 4 despite having a slower time because racer 3's id is lower. At the other end, racer 2 has a score of 3 because racers 3, 4, and 5 start after racer 2 and finish before racer 2 finishes.
 
Solution:
 
public class RacerRater {

    public static void main(String[] args) {
        
        Racer r1 = new Racer(2L,100L,200L);        
        Racer r2 = new Racer(3L, 110L, 190L);
        Racer r3 = new Racer(4L, 105L, 145L);
        Racer r4 = new Racer(1L, 90L, 150L);
        Racer r5 = new Racer(5L, 102L, 198L);
        
        
        Racer[] racers = new Racer[]{r1, r2, r3,r4,r5};
        
        Racer[] racersByStartTime = racers.clone();
        Arrays.sort(racersByStartTime, new Comparator<Racer>(){
            @Override
            public int compare(Racer r1, Racer r2) {
                return r1._start.compareTo(r2._start);
            }            
        });
        
        Racer[] racersByEndTime = racers.clone();
        Arrays.sort(racersByEndTime, new Comparator<Racer>(){
            @Override
            public int compare(Racer r1, Racer r2) {
                return r1._end.compareTo(r2._end);
            }            
        });
        
        
        List<Racer> buildingRacersByStartTime = new ArrayList<Racer>();
        buildingRacersByStartTime.add(racersByEndTime[0]);
        for(int i = 1;i<racersByEndTime.length; ++i)
        {
            Racer racer = racersByEndTime[i];            
            int lenBeforeInsersion = buildingRacersByStartTime.size();
            
            int whereToInsert = GetInsertLocation(buildingRacersByStartTime, racer);
            racer._score = lenBeforeInsersion - whereToInsert;
            buildingRacersByStartTime.add(whereToInsert, racer);
        }
        
        Racer[] racersByScore = racers.clone();
        Arrays.sort(racersByScore, new Comparator<Racer>(){
            @Override
            public int compare(Racer r1, Racer r2) {
                int t = r1._score - r2._score;
                if(t!=0)
                    return t;
                return r1._id.compareTo(r2._id);
            }            
        });
        
        System.out.println("=====input====");
        for(Racer r : racers)
            System.out.println(r._id+","+r._start+","+r._end);
        System.out.println("=====racers by start time====");
        for(Racer r : racersByStartTime)
            System.out.println(r._id+","+r._start+","+r._end);
        System.out.println("=====racers by end time====");
        for(Racer r : racersByEndTime)
            System.out.println(r._id+","+r._start+","+r._end);
        System.out.println("=====racers by score====");
        for(Racer r : racersByScore)
            System.out.println(r._id+",score:"+ r._score +","+r._start+","+r._end);
    }

    /**
     * return where to insert the racer while dynamically constructing the racer list in start time order
     */
    private static int GetInsertLocation(List<Racer> constructingRacersInStartTimeOrder, Racer r)
    {    
        int iLeft = 0;
        int iRight = constructingRacersInStartTimeOrder.size() - 1;
        while(iLeft<=iRight)
        {
            int iMid = (iLeft+iRight)/2;
            if(r._start == constructingRacersInStartTimeOrder.get(iMid)._start)
                return iMid;
            if(r._start < constructingRacersInStartTimeOrder.get(iMid)._start)
                iRight = iMid -1;
            else
                iLeft = iMid +1;
        }        
        return iLeft;
    }
}

public class Racer {
    Long _id;
    Long _start;
    Long _end;
    int _score;
    
    public Racer(Long id, Long start, Long end)
    {
        _id = id;
        _start = start;
        _end = end;
    }    
}

 

转载于:https://www.cnblogs.com/neweracoding/p/4216062.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值