PAT 甲級 1016 Phone Bills (25 分) (結構體排序,模擬題,巧妙算時間,坑點太多,debug了好久)


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 (≤), 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-linerecord. 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

0  、1測試點:沒有消費的用戶不能輸出

2測試點:on和off日期不在同一天卻在同一個小時

3測試點:on和off日期同一天同一個小時

題意:

一個長途電話公司收費規則如下:

長途電話每分鍾會有固定的收費,這取決於打電話時的時間。當一個顧客的長途電話接通時,這一刻的時間會記錄下來,同樣顧客掛斷電話時也是這樣。每個月,每分鍾通話的電話賬單就會寄給顧客。你的工作就是准備每月的賬單,給出一系列電話通話記錄。

每一個測試樣例都有兩個部分:費率結構和通話記錄

費率結構包含了一行24個非負整數記錄了一天24個小時每小時的長途電話費(美分/每分鍾)。

下一行包含了一個正數N(≤1000),之后有N條記錄,每一條電話通話記錄包含了顧客的姓名(一個20個字符的字符串,沒有空格) 時間(mm:dd:hh:mm)和文字on-line或者是off-line

對於每一個測試樣例,所有的數據都是一個月內的。每一條on-line記錄會有按時間先后排列的下一條記錄(相同顧客名)狀態為off-line和它構成一對。若有些on-line記錄並沒有可以配對的off-line記錄,則忽視這條記錄,同樣若只有off-line記錄,沒有與之對應的on-line記錄也忽視。可以保證至少有一條電話記錄能夠配對。你可以假設在同一時間同一顧客不會有兩條記錄。使用24小時時鍾來記錄時間

對於每一個測試樣例,你需要為每一個顧客打印出電話賬單

電話賬單打印順序按照顧客姓名的字母表順序。對每一個顧客,首先打印出顧客名字和賬單的月份。然后對每一個通話期間,用一行打印出開始時間和結束時間和日期(dd:hh:mm),持續時間(以分鍾為單位) ,收費。所有通話按照時間先后順序列出。最后打印出這個月的總費用

思路:

1.先把所有數據排個序,先按名字排,再時間

2.遍歷,用個is_out標記是不是已經匹配且輸出過(用於判斷該不該打印Total money),用last記錄上一次的狀態,如果上一次狀態是on-line且這次是off-line,那么{

  再判斷有沒有答應過名字(is_out)

  然后開始算時間和錢:時間和錢不用1分鍾1分鍾遍歷的算,先讓on的天數和小時數和off的相等,然后再減去多算的小時數,最后考慮分鍾

  //分鍾
  money-=last.m*p[last.h];//多的減去,注意是 p[last.h]
  money+=a[i].m*p[a[i].h];//少的加上,注意是 p[a[i].h]

}

3.字符串那里月份的處理卡了。。。哭泣

把整數加到字符串上

 

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    string s="";
    s+="0";
    int a=3;
    s+=a+'0';
    cout<<s<<endl;
    return 0;
 } 

4.is_out是換一個名字就要初始化的,忘了。。。難過。。。

最終滿分代碼:

#include<bits/stdc++.h>
using namespace std;
struct node{
    string name;
    int d;
    int h;
    int m;
    string state;
}a[1005];
bool cmp(node &x,node &y){
    if(x.name==y.name){
        if(x.d==y.d){
            if(x.h==y.h){
                return x.m<y.m;
            }else{
                return x.h<y.h;
            }
        }else{
            return x.d<y.d;
        }
    }else{
        return x.name<y.name;
    }
}

int main()
{
    double p[25];
    double sum_p=0;
    for(int i=0;i<=23;i++){
        cin>>p[i];
        p[i]*=0.01;
        sum_p+=p[i]*60;
    }
    int n;
    int month;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].name;
        scanf("%2d:%2d:%2d:%2d",&month,&a[i].d,&a[i].h,&a[i].m);
        cin>>a[i].state;
    }
    sort(a+1,a+1+n,cmp);
    /*for(int i=1;i<=n;i++){
        cout<<a[i].name<<" "<<a[i].d<<" "<<a[i].h<<" "<<a[i].m<<" "<<a[i].state<<endl;
    }*/
    node last;
    last.name="";
    int is_out=0;//坑點!是否有匹配上且輸出的 
    double totel=0;
    for(int i=1;i<=n;i++){
        if(i==1){
            last.name=a[i].name;
            last.d=a[i].d;
            last.h=a[i].h;
            last.m=a[i].m;
            last.state=a[i].state;
            is_out=0;
            continue;
        }
        if(a[i].name!=last.name){
            if(is_out)
            {
                //結算前一個人
                printf("Total amount: $%.2lf\n",totel);
                totel=0; 
            }    
            is_out=0; //這句導致第1,2個測試點過不了,名字一旦不同,不管有沒有輸出過,is_out要初始化 
        }else{
            //看看狀態對不對的上,對不上為"";
            if(last.state=="on-line"&&a[i].state=="off-line"){
                //計算時間
                int t=a[i].d-last.d;
                int t1=t*24*60;
                int t2=(a[i].h-last.h)*60;
                int t3=(a[i].m-last.m);
                //計算bill,不需要一分鍾一分鍾的跑,找到規律即可 
                double money=0;
                money+=t*sum_p;
                //小時 
                if(a[i].h>last.h)//比大小 
                {
                    for(int j=last.h;j<a[i].h;j++){
                        money+=p[j]*60;
                    }
                } 
                else{
                    for(int j=a[i].h;j<last.h;j++){
                        money-=p[j]*60;
                    }                    
                } 
                //分鍾 
                money-=last.m*p[last.h];//多的減去,注意是 p[last.h]
                money+=a[i].m*p[a[i].h];//少的加上,注意是 p[a[i].h]
                //如果這個人沒有被輸出過 
                if(is_out==0)
                {
                    cout<<a[i].name<<" ";
                    printf("%02d\n",month);
                    is_out=1;//匹配上且輸出了 
                }
                printf("%02d:%02d:%02d %02d:%02d:%02d ",last.d,last.h,last.m,a[i].d,a[i].h,a[i].m);
                printf("%d $%.2lf\n",t1+t2+t3,money);
                totel+=money;
            }
        } 
        last.name=a[i].name;
        last.d=a[i].d;
        last.h=a[i].h;
        last.m=a[i].m;
        last.state=a[i].state;        
    }
    if(is_out){//匹配上的才輸出 
        printf("Total amount: $%.2lf\n",totel);
    }
    return 0;
 } 

我自己編的測試數據

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
4
aaa 01:01:22:30 off-line
aaa 01:02:23:50 off-line
aaa 01:03:22:30 on-line
aaa 01:11:23:50 on-line

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
4
aaa 12:01:22:30 on-line
aaa 12:02:23:50 off-line
aaa 12:03:22:30 off-line
aaa 12:11:23:50 off-line

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
2
aaa 01:01:00:30 on-line
aaa 01:01:00:30 off-line


0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
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

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
4
CYJJ 01:01:07:00 off-line
CYJJ 01:01:05:59 on-line
CYJJ 01:01:05:00 on-line
CYJJ 01:01:07:59 off-line

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
18
CYLL 01:01:06:01 on-line
CYLL 01:01:07:00 off-line
CYLL 01:01:08:03 on-line
CYLL 01:01:08:09 off-line
CYLL 01:01:08:09 on-line
CYLL 01:02:00:01 off-line
CYLL 01:28:15:41 on-line
CYLL 01:29:02:24 on-line
CYLL 01:30:23:59 off-line
CYLL 01:30:24:59 off-line
CYLL 01:30:25:00 off-line
CYLL 01:30:25:25 off-line
MQ 01:01:06:01 on-line
MQ 01:02:03:04 on-line
MQ 01:03:04:05 on-line
MQ 01:03:04:06 off-line
YF 01:02:03:04 on-line
YF 01:02:03:05 on-line
View Code

 

看着真舒服!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM