PAT(A) - 1014. Waiting in Line (30)

来源:互联网 发布:工业控制网络电子版 编辑:程序博客网 时间:2024/06/04 23:19


Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:

  • The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (NM+1)st one will have to wait in a line behind the yellow line.
  • Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
  • Customer[i] will take T[i] minutes to have his/her transaction processed.
  • The first N customers are assumed to be served at 8:00am.

Now given the processing time of each customer, you are supposed to tell the exact time at which a customer has his/her business done.

For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer1 is served at window1 while customer2 is served at window2. Customer3 will wait in front of window1 and customer4 will wait in front of window2. Customer5 will wait behind the yellow line.

At 08:01, customer1 is done and customer5 enters the line in front of window1 since that line seems shorter now. Customer2 will leave at 08:02, customer4 at 08:06, customer3 at 08:07, and finally customer5 at 08:10.

Input

Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (<=20, number of windows), M (<=10, the maximum capacity of each line inside the yellow line), K (<=1000, number of customers), and Q (<=1000, number of customer queries).

The next line contains K positive integers, which are the processing time of the K customers.

The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.

Output

For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output "Sorry" instead.

Sample Input
2 2 7 51 2 6 4 3 534 23 4 5 6 7
Sample Output
08:0708:0608:1017:00Sorry

思路分析:一个银行排队模拟问题,可以用queue,我用的vector模拟。

全局说明: 定义用户结构体,包括id(编号),process(处理时间),end(结束时间)。定义window数组,表示每个窗口。

#define MAX_WINDOW 21 + 10
#define MAX_PERSON 1001 + 10

typedef struct {
    int id;
    int process;
    int end;
} Person;


Person person[MAX_PERSON];

vector<Person> window[MAX_WINDOW];


1.先初始化每个窗口的用户,按顺序依次安排到每个窗口上。定义一个世界时间,将8:00设置为起始点。世界时间表示从8:00开始经过了几分钟。

2.银行开门,按顺序处理每个队伍的用户。这里处理肯定是处理每个队伍最前面的那个用户。

3.模拟过程:

(1)遍历所有窗口,先找到每个窗口需要用时最短的那个人id和需要的时间t,然后所有窗口第一个人的处理时间减去t

(2)删除所有窗口最前面处理时间为0的人。(因为上一步减去t了,如果为0说明服务完成了)并记录处理完成的时间(世界时间 + t )

(3)检查是否还有用户没排队,如果false,什么也不干。

   如果为true,检查是否有空位置的队列。选择人数最少的队伍,push_back。

(4)世界时间不断增加,直到处理完所有用户。

4.输入查询的用户id,输出查询结果。

注意:这里有一个坑!Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output "Sorry" instead.这句话的意思是:超过17:00银行就不进行服务了。举个例子:小明16:59开始进行银行的服务,要处理10分钟,等他处理完世界时间是17:09,这个是要输出17:09的,不能输出sorry!!!也就是说不能按服务结束时间判断,要按服务开始的时间判断!你要是按后者做,,会发现只能得19分。。。而且你很懵逼,,一直找不到原因。


平时看看英语阅读理解吧。本来不难的题,就是因为几个生僻单词或是上下文语义理解不正确才导致错误的。而且做题,不能凭空按自己的生活常识来想象问题描述的是什么。要一字一句认真翻译准确,要不然,,唉,做题举步维艰,怎么错的也不知道。跟出题者的思维也有关系吧。。


#include <cstdio>#include <vector>#define MAX_WINDOW 21 + 10#define MAX_PERSON 1001 + 10using namespace std;typedef struct {    int id;    int process;    int end;} Person;Person person[MAX_PERSON];vector<Person> window[MAX_WINDOW];// 找见还需要处理最短时间的窗口int FindMin( int n ) {    int min = 0x3fffffff;    for( int i = 1; i <= n; i++ ) {        if( window[i].size() > 0 ) {            if( window[i][0].process < min ) {                min = window[i][0].process;            }        }    }    return min;}// 判断是否还有空位置的队列bool judge( int n, int m ) {    for( int i = 1; i <= n; i++ ) {        if( window[i].size() < m ) {            return true;        }    }    return false;}// 找到当前长度最短的队伍编号int minLength( int n, int m ) {    int min = 0x3fffffff;    int index = -1;    for( int i = 1; i <= n; i++ ) {        int num = window[i].size();        //printf( "窗口%d人数:%d\n", i, num );        if( ( num < min ) && ( num < m ) ) {            min = num;            index = i;        }    }    return index;}int main() {    //freopen( "123.txt", "r", stdin );    int n, m, k, q;    scanf( "%d%d%d%d", &n, &m, &k, &q );    for( int i = 1; i <= k; i++ ) {        person[i].id = i;        scanf( "%d", &person[i].process );    }    // 初始化操作,将前n * m名用户安放好    int index = 1;      // 初始化每个用户的编号    for( int i = 1; i <= m; i++ ) {        if( index > k ) break;        for( int j = 1; j <= n; j++ ) {            window[j].push_back( person[index] );            //printf( "%d用户在%d窗口\n", person[index].id, j );            index++;            if( index > k ) break;  // index > k的情况是初始化时就把用户都安排好了        }    }    int worldTime = 0;  // 世界时间从0开始    int count = 0;      // 已经处理完几个用户的数量    while( count < k ) {        int min = FindMin( n );        //printf( "需要操作%d分钟队列发生变化...\n", min );        // 开始处理每个窗口        for( int i = 1; i <= n; i++ ) {            if( window[i].empty() ) continue;   // 检查当前窗口是否有人,不加这句话会出现段错误            window[i][0].process = window[i][0].process - min;            if( window[i][0].process == 0 ) {                int id = window[i][0].id;                person[id].end = worldTime + min;                //printf( "%d用户操作完成\n", id );                count++;                // 删除掉完成的用户,肯定在最开头                window[i].erase( window[i].begin() );            }        }        bool flag, temp;        while( 1 ) {            if( index > k ) {                flag = false;                break;            }            // 检查是否还有空位置的队列            temp = judge( n, m );            if( temp == false ) break;            int lineIndex = minLength( n, m );            window[lineIndex].push_back( person[index] );            //printf( "%d用户新加入到窗口%d\n", index, lineIndex );            index++;        }        worldTime = worldTime + min;    // 世界时间增加        //printf( "世界时间:%d\n", worldTime );    }    int check;    int starand = 540;  // 开始进行服务的时间范围是 17:00之前有效,就是540分钟之前    for( int i = 1; i <= q; i++ ) {        scanf( "%d", &check );        int start = person[check].end - person[check].process;        int time = person[check].end;        //printf( "%d用户开始服务时间: %d\n", check, start );        if( start >= 540 ) {            printf( "Sorry\n" );        }        else {            int h = time / 60;            int m = time - h * 60;            printf( "%02d:%02d\n", h + 8, m );        }    }    return 0;}


0 0
原创粉丝点击