微軟201610 在線筆試 題目3 Registration Day

題目地址:
https://hihocoder.com/problemset/problem/1401
可提交代碼

題目3 : Registration Day

時間限制:10000ms
單點時限:1000ms
內存限制:256MB

描述

It’s H University’s Registration Day for new students. There are M offices in H University, numbered from 1 to M. Students need to visit some of them in a certain order to finish their registration procedures. The offices are in different places. So it takes K units of time to move from one office to another.

There is only one teacher in each office. It takes him/her some time to finish one student’s procedure. For different students this time may vary. At the same time the teacher can only serve one student so some students may need to wait outside until the teacher is available. Students who arrived at the office earlier will be served earlier. If multiple students arrived at the same time they will be served in ascending order by student number.

N new students need to finish his/her registration. They are numbered from 1 to N. The ith student’s student number is Si. He will be arrived at H University’s gate at time Ti. He needs to visit Pi offices in sequence which are Oi,1, Oi,2, … Oi,Pi. It takes him Wi,1, Wi,2, … Wi,Pi units of time to finish the procedure in respective offices. It also takes him K units of time to move from the gate to the first office.

For each student can you tell when his registration will be finished?

輸入

The first line contains 3 integers, N, M and K. (1 <= N <= 10000, 1 <= M <= 100, 1 <= K <= 1000)

The following N lines each describe a student.

For each line the first three integers are Si, Ti and Pi. Then following Pi pairs of integers: Oi,1, Wi,1, Oi,2, Wi,2, … Oi,Pi, Wi,Pi. (1 <= Si <= 2000000000, 1 <= Ti <= 10000, 1 <= Pi <= M, 1 <= Oi,j <= M, 1 <= Wi,j <= 1000)

輸出

For each student output the time when he finished the registration.

樣例提示

Student 1600012345 will be arrived at the gate at time 500. He needs to first visit Office #1 and then Office #2. He will be arrived at office #1 at time 600. He will leave office #1 at time 1100. Then He will arrive at office #2 at 1200. At the same time another student arrives at the same office too. His student number is smaller so he will be served first. He leaves Office #2 at 1700. End of registration.

Student 1600054321 will be arrived at the gate at time 1100. He will be arrived at Office #2 at 1200. Another student with smaller student number will be served first so he waits for his turn until 1700. He leaves Office #2 at 2000. End of registration.

樣例輸入

2 2 100
1600012345 500 2 1 500 2 500
1600054321 1100 1 2 300

樣例輸出

1700
2000

使用優先隊列的方法解決

代碼如下:

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct StudentInfo
{  
    int index;//第幾個學生0,1,2,3,4,...
    int ID;//學生學號,1600012345
    int time;//學生的結束時間
    int goWhich;//學生要去的office序號(vector中的序號0,1,2,3,4)

    //因爲STL裏優先隊列是大優先,故自身若要比s更優先,需要time更小,ID更小
    bool operator < (const StudentInfo &s) const
    {  
        if(time == s.time) return ID > s.ID;
        else return time > s.time;  
    }  
};  

struct Student
{  
    int ID;
    int arriveTime;
    int orderNum;
    vector<int> orderOffices;  
    vector<int> orderTimes;
};  

int main()  
{  
    priority_queue<StudentInfo> pQueue;

    int N,M,K;
    cin>>N>>M>>K;
    vector<Student> students(N);

    for (int i=0; i<N; i++)
    {
        //輸入
        cin>>students[i].ID;
        cin>>students[i].arriveTime;
        cin>>students[i].orderNum;
        for (int j=0; j<students[i].orderNum; j++)
        {
            int temp1,temp2;
            cin>>temp1>>temp2;
            students[i].orderOffices.push_back(temp1-1);//office序號從0開始
            students[i].orderTimes.push_back(temp2);
        }

        //加入隊列
        StudentInfo si;
        si.index = i;
        si.ID = students[i].ID;
        si.time = students[i].arriveTime+K;//初始時間爲到達時間+K
        si.goWhich = 0;//初始從第0個開始
        pQueue.push(si);
    }

    vector<int> res(N,0);
    vector<int> officeEndTime(M,0);//M個office的結束時間

    while(!pQueue.empty())
    {  
        //取最優值
        StudentInfo stuInfo = pQueue.top();  
        Student &stu = students[stuInfo.index];
        pQueue.pop();

        int curOffice = stu.orderOffices[stuInfo.goWhich];
        int procTime = stu.orderTimes[stuInfo.goWhich];

        //若當前office的結束時間小於stu的到達時間,則office會有一段時間閒置,stu到達後可直接處理 
        if (officeEndTime[curOffice] < stuInfo.time)
        {
            //更新office結束時間爲學生到達時間+處理時間
            officeEndTime[curOffice] = stuInfo.time + procTime;  
            //更新學生到達時間爲學生到達時間+學生處理時間+K
            stuInfo.time += procTime + K;
        }
        //若當前office的結束時間大於等於stu的到達時間,則stu需要等待一段時間
        else
        {  
            //更新office結束時間爲office結束時間+學生處理時間
            officeEndTime[curOffice] += procTime;  
            //更新學生到達時間爲office結束時間+學生處理時間
            stuInfo.time = officeEndTime[curOffice] + K;  
        }  


        if (stuInfo.goWhich == stu.orderNum-1)//若是最後一個點
        {
            res[stuInfo.index] = stuInfo.time - K;
        }
        else
        {
            stuInfo.goWhich ++;  
            pQueue.push(stuInfo);  
        }
    }  
    for(int i = 0; i < N; i ++)
    {  
        cout<<res[i]<<endl;
    }  
    return 0;  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章