PTA A1016

A1016 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

單詞

bills

英 /bɪls/ 美 /bɪls/

n. 賬單;議案(bill的複數)

n. (Bills)人名;(英、德)比爾斯

v. 開賬單(bill的第三人稱單數形式)

calendar

英 /'kælɪndə/ 美 /'kæləndɚ/

n. 日曆;[天] 曆法;日程表
vt. 將…列入表中;將…排入日程表

denoting

指示(denote的現在分詞)

toll

英 /təʊl/ 美 /tol/
vt. 徵收;敲鐘

n. 通行費;代價;鐘聲;傷亡人數

vi. 鳴鐘;徵稅

cent

英 /sent/ 美 /sɛnt/

n. 分;一分的硬幣;森特(等於半音程的百分之一)

n. (Cent)人名;(法)桑

chronologically

英 /krɔnə'lɔdʒikli/ 美 /krɔnə'lɔdʒikli/
adv. 按年代地

paired

英 /peəd/ 美 /peəd/
adj. [計] 成對的;配對的

v. 使成對;配合(pair的過去分詞)

alphabetical

英 /ælfə'betɪk(ə)l/ 美 /,ælfə'bɛtɪkl/
adj. 字母的;[計] 依字母順序的

題目分析

計算花費賬單,這題主要是排序和計算花費,排序可以使用qsort,我昨天還特地複習了一下,寫了篇博客【C/C++】qsort函數的使用方法和細節
先根據名字順序排序,然後在每個名字序列你根據時間排序(爲了方便比較我把時間全部轉化成了分鐘數),排好序後先判斷這個用戶有沒有有效記錄,如果有根據是否有兩個相鄰且狀態不同的記錄,如果是就輸出開始時間和結束時間計算分鐘數,計算賬單金額。
關於計算賬單金額,看上去很簡單,其實細分起來情況還是很多的,我一開始就是分情況做的,什麼一個小時內的情況,一天內多個個小時的情況,跨天可是小時數不滿一天,好多天的情況,這些情況都對應着一些極端數據,不考慮肯定是A不了的,弄起來很麻煩。後來我用了一個最佛系的方法,一分鐘一分鐘的遍歷.....最後我得出一個結論,能簡單解決的問題就不要分情況瞎折騰。

具體代碼

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define ONLINE 0
    #define OFFLINE 1

    int fare[24];

    struct record
    {
        char user[21];
        int min;
        int line_char;
    };
    
    int N, M;
    struct record r[1001];

    int convert_min(int d, int h, int m)
    {
        return d * 24 * 60 + h * 60 + m;
    }

    int compare_user(const void *p,const void *q)
    {
        return strcmp(((struct record*)p)->user, ((struct record*)q)->user);
    }
    
    int compare_min(const void *p, const void *q)
    {
        return ((struct record*)p)->min - ((struct record*)q)->min;
    }

    int main(void)
    {
        for (int i = 0; i < 24; i++)
            scanf("%d", &fare[i]);
        scanf("%d", &N);
        for (int i = 0; i < N; i++)
        {
            int d, h, m;
            char line[10];
            scanf("%s %d:%d:%d:%d %s", r[i].user, &M, &d, &h, &m, line);
            r[i].min = convert_min(d, h, m);
            if (strcmp(line, "on-line") == 0)
                r[i].line_char = ONLINE;
            else
                r[i].line_char = OFFLINE;
        }
        qsort(r, N, sizeof(struct record), compare_user);
        int begin = 0;
        char* temp = r[begin].user;
        int dayfare = 0;
        for (int i = 0; i < 24; i++)
            dayfare += fare[i];
        for (int i = 0; i <= N; )
        {       
            if (strcmp(temp, r[i].user) != 0)
            {
                qsort(r + begin, i - begin, sizeof(struct record), compare_min);
                int flag = 0;
                for (int n = begin; n < i; )
                {
                    if (r[n].line_char == ONLINE && r[n + 1].line_char == OFFLINE && n + 1 < i)
                    {
                        flag = 1;
                        n += 2;
                    }
                    else n++;
                }
                if (flag)
                {
                    printf("%s %02d\n", r[begin].user, M);
                    int sum = 0;
                    for (int n = begin; n < i; )
                    {
                        if (r[n].line_char == ONLINE && r[n + 1].line_char == OFFLINE && n + 1 < i)
                        {
                            printf("%02d:%02d:%02d", r[n].min / (24 * 60), r[n].min % (24 * 60) / 60, r[n].min % (24 * 60) % 60);
                            printf(" %02d:%02d:%02d", r[n + 1].min / (24 * 60), r[n + 1].min % (24 * 60) / 60, r[n + 1].min % (24 * 60) % 60);
                            printf(" %d", r[n + 1].min - r[n].min);
                            int mon = 0;
                            int start = r[n].min; int end = r[n + 1].min;
                            while (start != end )
                            {
                                mon += fare[(start % (60 * 24) / 60)];
                                start++;
                            }
                            sum += mon;
                            printf(" $%0.2f\n", mon / 100.0);
                            n += 2;
                        }
                        else n++;
                    }
                    printf("Total amount: $%0.2f\n", sum / 100.0);
                }
                begin = i;
                temp = r[begin].user;
            }
            else i++;
        }
        system("pause");
    }

參考博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章