diff --git a/PATAdvanced/1014.c b/PATAdvanced/1014.c new file mode 100644 index 0000000..6f9371b --- /dev/null +++ b/PATAdvanced/1014.c @@ -0,0 +1,136 @@ +/** + * 1014. Waiting in Line (30) + * + * 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 5 + * 1 2 6 4 3 534 2 + * 3 4 5 6 7 + * + * Sample Output + * + * 08:07 + * 08:06 + * 08:10 + * 17:00 + * Sorry + **/ + +#include + +#define LATE_FLAG -1 +#define FORWARD(I) ((I) = ((I) == 10) ? 0 : ((I) + 1)) +#define TIME_FRONT(I) time[queue[I][front[I]]] +#define TIME_REAR_PREVIOUS(I) time[queue[I][rear[I] == 0 ? 10 : (rear[I] - 1)]] + +int main() +{ + int N, M, K, Q, query; + int time[1000], queue[20][11] = {{0}}; + int front[20] = {0}, rear[20] = {0}, length[20] = {0}; + + scanf("%d %d %d %d", &N, &M, &K, &Q); + for(int i = 1; i <= K; i++) + scanf("%d", time + i); + + /* Total number of operations */ + int count = (K < M * N) ? (2 * K) : (K + M * N); + /* Doing dequeues and enqueues for every customer */ + for(int i = 1; i <= count; i++) + { + if(i > count - K) /* Dequeue in the last K operations */ + { + /* Find the next customer */ + int time_span = 9999, next = -1; + for(int j = 0; j < N; j++) if(length[j]) + { + if(TIME_FRONT(j) < time_span) + next = j, time_span = TIME_FRONT(j); + else if(next == -1 && TIME_FRONT(j) == LATE_FLAG) + next = j; + } + /* Dequeue */ + FORWARD(front[next]); + length[next]--; + } + if(i <= K) /* Enqueue in the first K operations */ + { + /* Find shortest queue */ + int shortest = 0; + for(int j = 0; j < N; j++) + if(length[shortest] > length[j]) + shortest = j; + /* Set flag or add time */ + int previous_time = TIME_REAR_PREVIOUS(shortest); + if(previous_time >= 9 * 60 || previous_time == LATE_FLAG) + time[i] = LATE_FLAG; + else + time[i] += previous_time; + /* Enqueue */ + queue[shortest][rear[shortest]] = i; + FORWARD(rear[shortest]); + length[shortest]++; + } + } + + /* Read queries and print answers */ + for(int i = 0; i < Q; i++) + { + scanf("%d", &query); + if(time[query] != LATE_FLAG) + printf("%02d:%02d\n", 8 + time[query] / 60, time[query] % 60); + else + printf("Sorry\n"); + } + + return 0; +} diff --git a/PATAdvanced/1016.c b/PATAdvanced/1016.c new file mode 100644 index 0000000..00f5e15 --- /dev/null +++ b/PATAdvanced/1016.c @@ -0,0 +1,160 @@ +/** + * 1016. Phone Bills (25) + * + * A long-distance telephone company charges its customers by the following + * rules: + * + * Making a long-distance call costs a certain amount per minute, depending on + * the time of day when the call is made. When a customer starts connecting a + * long-distance call, the time will be recorded, and so will be the time when + * the customer hangs up the phone. Every calendar month, a bill is sent to the + * customer for each minute called (at a rate determined by the time of day). + * Your job is to prepare the bills for each month, given a set of phone call + * records. + * + * Input Specification: + * + * Each input file contains one test case. Each case has two parts: the rate + * structure, and the phone call records. + * + * The rate structure consists of a line with 24 non-negative integers denoting + * the toll (cents/minute) from 00:00 - 01:00, the toll from 01:00 - 02:00, and + * so on for each hour in the day. + * + * The next line contains a positive number N (<= 1000), followed by N lines of + * records. Each phone call record consists of the name of the customer (string + * of up to 20 characters without space), the time and date (mm:dd:hh:mm), and + * the word "on-line" or "off-line". + * + * For each test case, all dates will be within a single month. Each "on-line" + * record is paired with the chronologically next record for the same customer + * provided it is an "off-line" record. Any "on-line" records that are not + * paired with an "off-line" record are ignored, as are "off-line" records not + * paired with an "on-line" record. It is guaranteed that at least one call is + * well paired in the input. You may assume that no two records for the same + * customer have the same time. Times are recorded using a 24-hour clock. + * + * Output Specification: + * + * For each test case, you must print a phone bill for each customer. + * + * Bills must be printed in alphabetical order of customers' names. For each + * customer, first print in a line the name of the customer and the month of + * the bill in the format shown by the sample. Then for each time period of a + * call, print in one line the beginning and ending time and date (dd:hh:mm), + * the lasting time (in minute) and the charge of the call. The calls must be + * listed in chronological order. Finally, print the total charge for the month + * in the format shown by the sample. + * + * Sample Input: + * + * 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 + * 10 + * CYLL 01:01:06:01 on-line + * CYLL 01:28:16:05 off-line + * CYJJ 01:01:07:00 off-line + * CYLL 01:01:08:03 off-line + * CYJJ 01:01:05:59 on-line + * aaa 01:01:01:03 on-line + * aaa 01:02:00:01 on-line + * CYLL 01:28:15:41 on-line + * aaa 01:05:02:24 on-line + * aaa 01:04:23:59 off-line + * + * Sample Output: + * + * CYJJ 01 + * 01:05:59 01:07:00 61 $12.10 + * Total amount: $12.10 + * CYLL 01 + * 01:06:01 01:08:03 122 $24.40 + * 28:15:41 28:16:05 24 $3.85 + * Total amount: $28.25 + * aaa 01 + * 02:00:01 04:23:59 4318 $638.80 + * Total amount: $638.80 + **/ + +#include +#include +#include + +/* Structure to store phone records */ +typedef struct { + char name[21]; + int month, day, hour, min, time, state; +}Record, *pRecord; + +/* Compare first by name, then by date and time */ +int cmp(const void *record1, const void *record2) +{ + pRecord r1 = *(pRecord*)record1, r2 = *(pRecord*)record2; + return strcmp(r1->name, r2->name) ? + strcmp(r1->name, r2->name) : r1->time - r2->time; +} + +/* Calculate the charge of the call with start record p1 and end record p2 */ +int calccharge(pRecord p1, pRecord p2, int toll[]) +{ + int charge = 0, start = p1->time, end = p2->time, h, time1, time2; + + for(time1 = start; time1 < end; time1 = time2) + { /* Add the charge hour by hour */ + time2 = (time1 / 60 + 1) * 60; /* time2 will be the time of next hour */ + h = time1 / 60 % 24; /* h will be the index of the hour */ + charge += ((time2 > end ? end : time2) - time1) * toll[h]; + } + + return charge; +} + +int main() +{ + char state[9]; + int N, toll[24], charge, charge_total = 0; + Record records[1001] = {0}; + pRecord precords[1001] = {0}, *p = precords; + + /* Read data */ + for(int i = 0; i < 24; i++) + scanf("%d", toll + i); + scanf("%d", &N); + for(int i = 0; i < N; i++, p++) + { + *p = records + i; + scanf("%s %d:%d:%d:%d %s", (*p)->name, + &(*p)->month, &(*p)->day, &(*p)->hour, &(*p)->min, state); + (*p)->time = ((*p)->day * 24 + (*p)->hour) * 60 + (*p)->min; + (*p)->state = strcmp(state, "on-line") ? 0 : 1; + } + + /* Sort first by name, then by date and time */ + qsort(precords, N, sizeof(pRecord), cmp); + + /* Print phone bill one by one */ + for(p = precords + 1; *p; p++) + { + if(strcmp((*p)->name, (*(p - 1))->name)) + { /* A new customer, print last total amount if any */ + if(charge_total) + printf("Total amount: $%.2f\n", charge_total * 1e-2); + charge_total = 0; + } + else if((*(p - 1))->state == 1 && (*p)->state == 0) + { /* Still the same customer, finding on/off record pair */ + if(charge_total == 0) + printf("%s %02d\n", (*p)->name, (*p)->month); + charge = calccharge(*(p - 1), *p, toll); + charge_total += charge; + /* Print info of this call */ + printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n", + (*(p - 1))->day, (*(p - 1))->hour, (*(p - 1))->min, + (*p)->day, (*p)->hour, (*p)->min, + (*p)->time - (*(p - 1))->time, charge * 1e-2); + } + } + if(charge_total) + printf("Total amount: $%.2f\n", charge_total * 1e-2); + + return 0; +} diff --git a/PATBasic/1010.c b/PATBasic/1010.c index e38c420..8d71e8e 100644 --- a/PATBasic/1010.c +++ b/PATBasic/1010.c @@ -23,10 +23,13 @@ int main() int coef, index, count = 0; while(scanf("%d %d", &coef, &index) != EOF) - if(index) /* Constant terms result in zero, so no output for 0 index */ - printf("%c%d %d", count++ ? ' ' : '\0', coef * index, index - 1); + if(index) /* Constant terms result in zero */ + { + if(count++) putchar(' '); + printf("%d %d", coef * index, index - 1); + } - /* For zero polynomial or constant, the result is zero polynomial */ + /* Zero polynomial or constant */ if(count == 0) puts("0 0"); diff --git a/PATBasic/1029.c b/PATBasic/1029.c index fb3dfd4..2d38e77 100644 --- a/PATBasic/1029.c +++ b/PATBasic/1029.c @@ -28,8 +28,7 @@ int main() int printed[128] = {0}; char c, line[82]; - scanf("%s", line); - while((c = getchar()) != '\n') ; + gets(line); while((c = getchar()) != '\n') printed[toupper(c)]++; diff --git a/PATBasic/1030.c b/PATBasic/1030.c index 2aef276..e2b49da 100644 --- a/PATBasic/1030.c +++ b/PATBasic/1030.c @@ -34,7 +34,7 @@ int main() qsort(data, N, sizeof(int), comp); /* sort */ int max = 0; /* find */ - for(int first = 0, last = 0; last < N; first++) + for(int first = 0, last = 0; last < N && max < N - first; first++) { while(last < N && data[last] <= 1L * data[first] * p) last++; diff --git a/PATBasic/1052.c b/PATBasic/1052.c index 7b24deb..a194cc7 100644 --- a/PATBasic/1052.c +++ b/PATBasic/1052.c @@ -51,10 +51,10 @@ int main() { for(int i = 0; i < 5; i++) scanf("%d", m + i); if(m[0] > 0 && m[0] <= 10 && *symbols[0][--m[0]] - && m[1] > 0 && m[0] <= 10 && *symbols[1][--m[1]] - && m[2] > 0 && m[0] <= 10 && *symbols[2][--m[2]] - && m[3] > 0 && m[0] <= 10 && *symbols[1][--m[3]] - && m[4] > 0 && m[0] <= 10 && *symbols[0][--m[4]]) + && m[1] > 0 && m[1] <= 10 && *symbols[1][--m[1]] + && m[2] > 0 && m[2] <= 10 && *symbols[2][--m[2]] + && m[3] > 0 && m[3] <= 10 && *symbols[1][--m[3]] + && m[4] > 0 && m[4] <= 10 && *symbols[0][--m[4]]) printf("%s(%s%s%s)%s\n", symbols[0][m[0]], symbols[1][m[1]], symbols[2][m[2]], symbols[1][m[3]], symbols[0][m[4]]); else diff --git a/README.md b/README.md index 675b9b8..06997b2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ 欢迎讨论 oliver_lew@outlook.com -* 简书中写了代码的解释 - * [PAT Basic](https://www.patest.cn/contests/pat-b-practise) (已经刷完1001-1080): http://www.jianshu.com/p/c2b557516b50 - * [PAT Advanced](https://www.patest.cn/contests/pat-a-practise) (刚刚开始): http://www.jianshu.com/p/8944b15f8194 +发现问题也欢迎提交[issue](https://github.com/OliverLew/PAT/issues)或者[pull request](https://github.com/OliverLew/PAT/pulls) + +## 解题说明 + +在简书上写了代码的解释 +* PAT Basic ([原题链接](https://www.patest.cn/contests/pat-b-practise),已经刷完1001-1080): http://www.jianshu.com/p/c2b557516b50 +* PAT Advanced ([原题链接](https://www.patest.cn/contests/pat-a-practise),刚刚开始): http://www.jianshu.com/p/8944b15f8194