GVKun编程网logo

PAT_A1016#Phone Bills

3

想了解PAT_A1016#PhoneBills的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于1016PhoneBills、1016PhoneBills(25分)、A1016Phone

想了解PAT_A1016#Phone Bills的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于1016 Phone Bills、1016 Phone Bills (25 分)、A1016 Phone Bills (25)(25 分)、PAT 1016. Phone Bills的新知识。

本文目录一览:

PAT_A1016#Phone Bills

PAT_A1016#Phone Bills

Source:

PAT A1016 Phone Bills (25 分)

Description:

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

Keys:

  • 模拟题

Code:

  1 /*
  2 Data: 2019-07-17 19:24:07
  3 Problem: PAT_A1016#Phone Bills
  4 AC: 53:32
  5 
  6 题目大意:
  7 统计月度话费账单
  8 输入:
  9 第一行给出,各小时的话费权重cent/minute
 10 第二行给出,通话数N<=1e3
 11 接下来N行,name,time,status(on/off)
 12 输出:
 13 打印各个用户的账单,姓名递增
 14 name,month
 15 start,end,time,costs
 16 total amount
 17 */
 18 
 19 #include<cstdio>
 20 #include<vector>
 21 #include<string>
 22 #include<iostream>
 23 #include<algorithm>
 24 using namespace std;
 25 const int M=1e3+10,H=24;
 26 struct node
 27 {
 28     string name,status;
 29     string time;
 30 }info[M];
 31 struct mode
 32 {
 33     int dd,hh,mm;
 34 };
 35 int n,w[H];
 36 
 37 bool cmp(const node &a,const node &b)
 38 {
 39     if(a.name != b.name)
 40         return a.name < b.name;
 41     else
 42         return a.time < b.time;
 43 }
 44 
 45 mode Time(string s)
 46 {
 47     mode t;
 48     t.dd = atoi(s.substr(3,2).c_str());
 49     t.hh = atoi(s.substr(6,2).c_str());
 50     t.mm = atoi(s.substr(9,2).c_str());
 51     return t;
 52 }
 53 
 54 int Pay(string s1,string s2,int &time,int &cost)
 55 {
 56     mode t1 = Time(s1);
 57     mode t2 = Time(s2);
 58     while(t1.dd!=t2.dd || t1.hh!=t2.hh || t1.mm!=t2.mm)
 59     {
 60         time++;
 61         cost += w[t1.hh];
 62         t1.mm++;
 63         if(t1.mm==60)
 64         {
 65             t1.mm=0;
 66             t1.hh++;
 67         }
 68         if(t1.hh==24)
 69         {
 70             t1.hh=0;
 71             t1.dd++;
 72         }
 73     }
 74     return cost;
 75 }
 76 
 77 int main()
 78 {
 79 #ifdef    ONLINE_JUDGE
 80 #else
 81     freopen("Test.txt","r",stdin);
 82 #endif
 83 
 84     for(int i=0; i<H; i++)
 85         scanf("%d",&w[i]);
 86     scanf("%d",&n);
 87     for(int i=0; i<n; i++)
 88         cin >> info[i].name >> info[i].time >> info[i].status;
 89     sort(info,info+n,cmp);
 90     for(int i=1; i<n; i++)
 91     {
 92         int valid=0,bill=0;
 93         while(i<n && info[i-1].name==info[i].name)
 94         {
 95             int cost=0,time=0;
 96             if(info[i-1].status=="on-line"&&info[i].status=="off-line")
 97             {
 98                 if(!valid)  cout << info[i].name << " " << info[0].time.substr(0,2) << endl;
 99                 valid=1;
100                 bill += Pay(info[i-1].time,info[i].time,cost);
101                 cout << info[i-1].time.substr(3) << " " << info[i].time.substr(3);
102                 printf(" %d $%.2f\n",1.0*cost/100.0);
103             }
104             i++;
105         }
106         if(valid)   printf("Total amount: $%.2f\n",1.0*bill/100.0);
107     }
108 
109     return 0;
110 }

1016 Phone Bills

1016 Phone Bills

题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805493648703488

代码有点问题,过不了测试样例,先贴出来,有空改,代码如下:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<queue>
  5 #include<cstdio>
  6 #include<fstream>
  7 using namespace std;
  8 const string online = "on-line";
  9 const string offline = "off-line";
 10 float rate[24];
 11 struct infor{
 12     string name;
 13     string time;
 14     string line;
 15     int bianhao;
 16     int h;
 17     int m;
 18     int s;
 19     int he;
 20     void init(){
 21         bianhao = (int)((time[0]-''0'')*10)+(int)(time[1]-''0'');
 22         h = (int)((time[3]-''0'')*10)+(int)(time[4]-''0'');
 23         m = (int)((time[6]-''0'')*10)+(int)(time[7]-''0'');
 24         s = (int)((time[9]-''0'')*10)+(int)(time[10]-''0'');
 25     }
 26     void qiuhe(){
 27         he = h*3600+m*60+s;
 28     }
 29     friend bool operator <(const infor &in1,const infor &in2){
 30         if(in2.bianhao < in1.bianhao) return true;
 31         else if(in2.h > in1.h) return true;
 32         else if(in2.m > in1.m) return true;
 33         else if(in2.s > in1.s) return true;
 34         else return false;
 35     }
 36 };
 37 bool comp(string s1,string s2){
 38     return s1 < s2;
 39 }
 40 bool fin(string s[],string a,int x){
 41     for(int i = 0; i < x; i++){
 42         if(s[i] == a) return true;
 43     }
 44     return false;
 45 }
 46 int sum(int a1,int a2){
 47     //cout << a1-a2;
 48     return a1-a2;
 49 }
 50 float qianshu(int x,int y,int j,int i){                 //2 1 2 1
 51     int stem=0;
 52     if(i == j) return ((x-y)*rate[i])/100.0;
 53     else if(i == j-1) return ((j*7000-y)*rate[i]+(x-j*7000)*rate[j])/100.0;
 54     else{
 55         for(int k = j-i; k>=1; k--){
 56             stem += (i+1)*3600+rate[i+1];
 57         }
 58         stem += (j*7000-y)*rate[i]+(x-j*7000)*rate[j];
 59         return stem/100.0;
 60     }
 61 }
 62 int main(){
 63     priority_queue<infor> q1;
 64     priority_queue<infor> q2;
 65     string per[501];
 66     freopen("in.txt","r",stdin);
 67     float qian[501];
 68     int n,count = 0, cou = 0,shu=0;
 69     for(int i = 0; i < 24; i++){
 70         scanf("%f",&rate[i]);
 71     }
 72     scanf("%d",&n);
 73     infor stem[1003];
 74     while(n--){
 75         cin >> stem[cou].name >> stem[cou].time >> stem[cou].line;
 76         //int st = per.find(stem[cou].name);
 77         if(!fin(per,stem[cou].name,count)) per[count++] = stem[cou].name;
 78         stem[cou].init();
 79         stem[cou].qiuhe();
 80         cou++;
 81         //q.push(stem);
 82     }
 83     sort(per,per+count,comp);
 84     for(int i = 0; i < count; i++){
 85         cout << per[i] << endl;
 86     }
 87     for(int i = 0; i < count; i++){
 88         for(int j = 0; j < cou; j++){
 89             if(per[i] == stem[j].name && stem[j].line == online){
 90                 q1.push(stem[j]);
 91             }
 92             else if(per[i] == stem[j].name && stem[j].line == offline){
 93                 q2.push(stem[j]);
 94             }
 95         }
 96         float qiansh = 0;
 97         for(int i = 0; i < q2.size(); i++){
 98             while(q2.top().bianhao != q1.top().bianhao) q1.pop();
 99             cout << per[i] << " " << q2.top().bianhao << endl;
100             cout << q1.top().h << ":" << q1.top().m << ":" << q1.top().s << " "
101                 << q2.top().h << ":" << q2.top().m << ":" << q2.top().s << " ";
102             int he_stem = sum(q2.top().he,q1.top().he);
103             float qian = qianshu(q2.top().he,q1.top().he,q2.top().h,q1.top().h);
104             cout << he_stem << " " <<  "$" << qian << endl;
105             qiansh += qian;
106         }
107         cout << "Total amount:" << "$" << qiansh << endl;
108         while(!q1.empty()) q1.pop();
109         while(!q2.empty()) q2.pop();
110     }
111     return 0;
112 }

 

1016 Phone Bills (25 分)

1016 Phone Bills (25 分)

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

分析:排序题,有些复杂,参考了晴神笔记。。
  1 #include<cstdio>
  2 #include<string.h>
  3 #include<algorithm>
  4 using namespace std;
  5 const int maxn = 1010;
  6 int toll[25];//资费
  7 struct Record
  8 {
  9     char name[25];//姓名
 10     int month, dd, hh, mm;//月份、日、时、分
 11     bool status;//status==true表示该记录为on-line,否则为off-line
 12 }rec[maxn],temp;
 13 bool cmp(Record a, Record b)
 14 {
 15     int s = strcmp(a.name, b.name);
 16     if (s != 0)return s < 0;//优先按名字典序从小到大排序
 17     else if (a.month != b.month)return a.month < b.month;//按月份从小到大排序
 18     else if (a.dd != b.dd)return a.dd < b.dd;//按日期从小到大排序
 19     else if (a.hh != b.hh)return a.hh < b.hh;//按小时从小到大排序
 20     else return a.mm < b.mm;//按分钟从小到大排序
 21 }
 22 void get_ans(int on, int off, int &time, int &money)
 23 {
 24     temp = rec[on];
 25     while (temp.dd < rec[off].dd || temp.hh < rec[off].hh || temp.mm < rec[off].mm)
 26     {
 27         time++;//该次记录总时间加一分钟
 28         money += toll[temp.hh];//话费增加toll[temp.hh]
 29         temp.mm++;//当前时间加1min
 30         if (temp.mm >= 60)//当前分钟数达到60
 31         {
 32             temp.mm = 0;//进入下一个小时
 33             temp.hh++;
 34         }
 35         if (temp.hh >= 24)//当前小时数达到24
 36         {
 37             temp.hh = 0;//进入下一天
 38             temp.dd++;
 39 
 40         }
 41     }
 42 }
 43 
 44 int main()
 45 {
 46 #ifdef ONLINE_JUDGE
 47 #else
 48     freopen("1.txt", "r", stdin);
 49 #endif
 50 
 51     for (int i = 0; i < 24; i++)
 52     {
 53         scanf("%d", &toll[i]);//资费
 54     }
 55     int n;
 56     scanf("%d", &n);//记录数
 57     char line[10];//临时存放on-line或off-line的输入
 58     for (int i = 0; i < n; i++)
 59     {
 60         scanf("%s", rec[i].name);
 61         scanf("%d:%d:%d:%d", &rec[i].month, &rec[i].dd, &rec[i].hh, &rec[i].mm);
 62         scanf("%s", line);
 63         if (strcmp(line, "on-line") == 0)
 64         {
 65             rec[i].status = true;//如果是on-line,则令status为true
 66         }
 67         else
 68         {
 69             rec[i].status = false;//如果是off-line,则令status为false
 70         }
 71     }
 72     sort(rec, rec + n, cmp);//排序
 73     int on = 0, off, next;//on和off为配对的两条记录,next为下一个用户
 74     while (on < n)
 75     {
 76         int needPrint = 0;//needPrint表示该用户是否需要输出
 77         next = on; //从当前位置开始寻找下一个用户
 78         while (next < n&&strcmp(rec[next].name, rec[on].name) == 0)
 79         {
 80             if (needPrint == 0 && rec[next].status == true)
 81             {
 82                 needPrint = 1;//找到on,置needPrint为1
 83             }
 84             else if (needPrint == 1 && rec[next].status == false)
 85             {
 86                 needPrint = 2;//在on之后如果找到off,置needPrint为2
 87             }
 88             next++;//next自增,直到找到不同名字,即下一个用户
 89         }
 90         if (needPrint < 2)//没有找到配对的on-off
 91         {
 92             on = next;
 93             continue;
 94         }
 95         int AllMoney = 0;//总共花费的钱
 96         printf("%s %02d\n", rec[on].name, rec[on].month);
 97         while (on < next)//寻找该用户的所有配对
 98         {
 99             while (on < next - 1 && !(rec[on].status == true && rec[on + 1].status == false))
100             {
101                 on++;//直到找到连续的on-line和off-line
102             }
103             off = on +1;//off必须是on的下一个
104             if (off == next)//已经输出完毕所有配对的on-line和off-line
105             {
106                 on = next;
107                 break;
108             }
109             printf("%02d:%02d:%02d ", rec[on].dd, rec[on].hh, rec[on].mm);
110             printf("%02d:%02d:%02d ", rec[off].dd, rec[off].hh, rec[off].mm);
111             int time = 0, money = 0;//时间、单次记录花费的钱
112             get_ans(on, off, time, money);//计算on到off内的时间和金钱
113             AllMoney += money;//总金额加上该次记录的钱
114             printf("%d $%.2f\n", time, money / 100.0);
115             on = off + 1;//完成一个配对,从off+1开始找下一对
116         }
117         printf("Total amount: $%.2f\n", AllMoney / 100.0);
118     }
119     return 0;
120 }

 

A1016 Phone Bills (25)(25 分)

A1016 Phone Bills (25)(25 分)

A1016 Phone Bills (25)(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

思路

这里面时间轴的思想非常重要。

日期和时间的排序,以及,分钟数计算时间差的手段

K&R的书里竟然有错,在strcmp函数介绍里,不过总算是明白cmp函数返回值得原理。

升序是a>b返回正值

降序是a<b返回正值

分钟计时的代码也很不错

while(temp.dd < rec[off].dd || temp.hh < rec[off].hh || temp.mm < rec[off].mm) {
        (*time)++;
        (*money)+= toll[temp.hh];
        temp.mm++;
        if(temp.mm >= 60) {
            temp.mm = 0;
            temp.hh++;
        }
        if(temp.hh >= 24) {
            temp.hh = 0;
            temp.dd++;
        }
    }

AC代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define maxn  1010
int toll[25];
struct Record {
    char name[25];
    int month,dd,hh,mm;
    bool status;
} rec[maxn],temp;
int cmp(const void* a,const void* b) {
    struct Record*aa=(Record*)a;
    struct Record*bb=(Record*)b;
//  struct Record*aa=a;
//  struct Record*bb=b;
    
    int s = strcmp(aa->name,bb->name);
/*  aa->name<bb->name时,返回负值,aa->name=bb->name时,返回0 ,aa->name>bb->name时,返回正值 
    if(s != 0) return s > 0;*/
/*  为使qsort达成升序排列 
    在函数cmp中,如果第一个参数小于第二个参数,它必须返回一个负值;
    如果第一个参数等于第二个参数,它必须返回0;
    如果第一个参数大于第二个参数,它必须返回一个正值。 
    */
    
    if(s != 0) return s>0 ? 1:-1;/*客户的名字,字典序,升序*/
    else if(aa->month != bb->month) return aa->month > bb->month;/*月份升序*/
    else if(aa->dd != bb->dd) return aa->dd > bb->dd;/*日期升序*/
    else if(aa->hh != bb->hh) return aa->hh > bb->hh;/*钟点升序*/
    else return aa->mm > bb->mm;/*分钟升序,数据限制,没有到分钟都全部相同的记录*/
}
void get_ans(int on,int off,int* time,int* money) {
    temp = rec[on];
    while(temp.dd < rec[off].dd || temp.hh < rec[off].hh || temp.mm < rec[off].mm) {
        (*time)++;
        (*money)+= toll[temp.hh];
        temp.mm++;
        if(temp.mm >= 60) {
            temp.mm = 0;
            temp.hh++;
        }
        if(temp.hh >= 24) {
            temp.hh = 0;
            temp.dd++;
        }
    }
}
int main() {
    for(int i = 0; i < 24; i++) {
        scanf("%d",&toll[i]);
    }
    int n;
    scanf("%d",&n);
    char line[10];
    for(int i = 0; i < n; i++) {
        scanf("%s",rec[i].name);
        scanf("%d:%d:%d:%d",&rec[i].month,&rec[i].dd,&rec[i].hh,&rec[i].mm);
        scanf("%s",line);
        if(strcmp(line,"on-line") == 0) {/*字符串相等*/
            rec[i].status = true;
        } else {
            rec[i].status = false;
        }
    }
    qsort(rec,n,sizeof (struct Record),cmp);/*排序有问题*/
//    for(int i=0;i<n;i++){
//      printf("%s ",rec[i].name);
//      printf("%d:%d:%d:%d\n",rec[i].month,rec[i].dd,rec[i].hh,rec[i].mm);
//    //    printf("%s",rec[i].status);
//      
//  }
    int on = 0,off,next;//next下一位客户
    while(on < n) {
        int needPrint = 0;
        next = on;
        while(next < n && strcmp(rec[next].name,rec[on].name) == 0) {
            if(needPrint == 0 && rec[next].status == true) {
                needPrint = 1;
            } else if(needPrint == 1 && rec[next].status == false) {
                needPrint = 2;
            }
            next++;
        }/*在同一客户记录中寻找有无匹配的时间轴记录*/
        if(needPrint < 2) {/*没有成对的,时间轴相邻的on-line 与off-line*/
            on = next;
            continue;/*跳过这些记录*/
        }
        int AllMoney = 0;
        printf("%s %02d\n",rec[on].name,rec[on].month);/*该用户存在有效通话记录*/
        while(on < next) {
            while(on < next - 1
                  && !(rec[on].status == true && rec[on + 1].status == false)) {
                on++;/*直到找到连续的on-line和off-line*/
            }
            off = on + 1;
            if(off == next) {
                on = next;
                break;
            }
            printf("%02d:%02d:%02d ",rec[on].dd,rec[on].hh,rec[on].mm);
            printf("%02d:%02d:%02d ",rec[off].dd,rec[off].hh,rec[off].mm);
            int time = 0,money = 0;
            get_ans(on,&time,&money);
            AllMoney += money;
            printf("%d $%.2f\n",time,money / 100.0);
            on = off + 1;
        }
        printf("Total amount: $%.2f\n",AllMoney / 100.0);
    }
    return 0;
}

PAT 1016. Phone Bills

PAT 1016. Phone Bills

这道题目有两点要考虑的:1.如何匹配:其实条件很简单,只需要先按每个人的名字分组,然后按时间排序,只有当上一个记录是on-line且当前记录是off-line的时候,才匹配成功;2.如何计算一个时间段内的钱:因为是在一个月内的,所以可以写一个函数计算出从月初到某个时间点的所有花费,那么两个时间段减一减就可以了。也可以先把多出的分钟单独计算掉,然后就只计算小时的差距。

最坑爹的陷阱是:如果某个顾客的记录并没有匹配成功的,则说明信息都不显示。这我是网上看到的思路,我始终觉得题目里面没有这么说或者这么暗示。觉得坑爹!

Python代码:

import sys
import datetime
toll=[int(x) for x in raw_input().split()]

N=int(raw_input())
dic={}

timeFormat=''%m:%d:%H:%M'' #时间格式
for i in range(0,N):
	line=raw_input().split()
	if not dic.has_key(line[0]):
		dic[line[0]]=[]
	dic[line[0]].append((line[1],line[2])) #字典里面,每个人对应一个时间列表


def calc_day(): #计算一天所需要的钱
	sum=0
	for i in range(0,24):
		sum=sum+toll[i]*60
	return sum
def calc(beg,end):#计算从时间点beg到end的钱
	beg=datetime.datetime.strptime(beg,timeFormat)
	end=datetime.datetime.strptime(end,timeFormat)
	money=-beg.minute*toll[beg.hour]+end.minute*toll[end.hour]#先计算单出来的分钟
	aday=beg.hour
	bday=end.hour+24
	for i in range(aday,bday): #在计算从beg的hour到end的hour+24的钱,
                                   #加24是为了保证end.hour>beg.hour
		money=money+toll[i%24]*60
	money=money+(end.day-beg.day-1)*calc_day() #计算整天的钱
	min_diff=int((end-beg).total_seconds())/60 #计算分钟差
	return (min_diff,money/100.0)

for one in sorted(dic.keys()):
	dic[one].sort()
	lst=('''','''')
	lstItem=dic[one]
	sum=0
	isUsed=False #用于检测该用户是否至少有一次匹配成功的
	for it in lstItem:
		if lst[1]==''on-line'' and it[1]==''off-line'':
			if not isUsed:#如果有的话,则输出用户的信息
				isUsed=True
				print one,
				print lstItem[0][0][:2]
			beg=lst[0]
			end=it[0]
			(min_diff,money)=calc(beg,end)
			print beg[3:],end[3:],min_diff,''$%.2f''%(money) #输出时间段
			sum=sum+money
		lst=it
	if isUsed:#输出总额
		print ''Total amount: $%.2f''%(sum)

今天的关于PAT_A1016#Phone Bills的分享已经结束,谢谢您的关注,如果想了解更多关于1016 Phone Bills、1016 Phone Bills (25 分)、A1016 Phone Bills (25)(25 分)、PAT 1016. Phone Bills的相关知识,请在本站进行查询。

本文标签: