浙大PAT 甲级A1016 Phone Bills(排序、数据记录配对)

14 篇文章 0 订阅
该博客主要介绍了一个C++程序,用于处理电话通话记录数据。程序首先按客户姓名和时间排序通话记录,然后寻找匹配的通话记录,即属于同一客户且依次为on-line和off-line的记录。匹配的通话记录会被用来计算通话时长和费用,并输出。程序还考虑了无匹配记录的客户情况,以及在处理完一个客户的所有通话记录后输出总费用。测试数据展示了程序的正确性和预期输出。
摘要由CSDN通过智能技术生成

PAT - A1016 Phone Bills (25 分) https://pintia.cn/problem-sets/994805342720868352/problems/994805493648703488
题目-1题目-2

大致思路:

按 客户名字、时间 将输入的通话记录数据排序,找匹配的通话记录(关键点),输出并统计时长和费用。

注意点:
  1. 无匹配记录的客户 什么也不能输出。
  2. 两条通话记录匹配条件:
    ①相邻 ;
    ②属于同一个客户(自己栽在这里…代码后附测试数据);
    ③前一个为on-line后一个为off-line。
  3. 输出格式。
通过代码(C/C++):
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

struct record{
    char name[21];
    int MM, dd, HH, mm;
    int flag;   // 1代表on-line,-1代表off-line
}records[1000];

bool cmp(record a, record b){
    if(strcmp(a.name, b.name))  return strcmp(a.name, b.name)<0;
    else if(a.MM!=b.MM) return a.MM<b.MM;
    else if(a.dd!=b.dd) return a.dd<b.dd;
    else if(a.HH!=b.HH) return a.HH<b.HH;
    else return a.mm<b.mm;
}

int main(){
    int tolls[24];
    for(int i=0;i<24;i++)   scanf("%d", tolls+i);
    int N;
    scanf("%d", &N);
    char flag_temp[10];
    for(int i=0;i<N;i++){
        scanf("%s %d:%d:%d:%d %s", records[i].name, &records[i].MM, &records[i].dd, &records[i].HH, &records[i].mm, flag_temp);
        records[i].flag = strcmp(flag_temp, "on-line")==0 ? 1 : -1;
    }
    sort(records, records+N, cmp);
    int month=records[0].MM;    //题目保证所有测试数据都在同一个月份,故后续不用再判断处理
    double amount=0.0;
    int i=0;
    while(i<N-1){   //后续用到下标i+1,为避免越界此处不能为N
        if(i>0 && strcmp(records[i].name, records[i-1].name) && amount){  //前一个客户处理完毕,且有有效数据(总费用非零)
            printf("Total amount: $%.2f\n", amount);
            amount=0.0;
        }
        if(records[i].flag==-1 || records[i+1].flag==1 || strcmp(records[i].name, records[i+1].name)){ //【关键点】本记录无效,跳过
            i++;
        }else{  //本记录和下一条记录匹配(属于同一个客户且依次为on-line和off-line),有效
            if(amount==0)   printf("%s %02d\n", records[i].name, month);    //该客户之前已有通话记录统计到,补打印名字和月份
            printf("%02d:%02d:%02d %02d:%02d:%02d ", records[i].dd, records[i].HH, records[i].mm,
                                                records[i+1].dd, records[i+1].HH, records[i+1].mm);
            int duration=0;
            double charge=0.0;
            while(records[i].dd<records[i+1].dd || records[i].HH<records[i+1].HH || records[i].mm< records[i+1].mm){    //统计单次通话时长和费用
                records[i].mm++;
                duration++;
                charge += tolls[records[i].HH]/100.0;
                if(records[i].mm==60){
                    records[i].mm=0;
                    records[i].HH++;
                }
                if(records[i].HH==24){
                    records[i].HH=0;
                    records[i].dd++;
                }
            }
            printf("%d $%.2f\n", duration, charge);
            amount += charge;
            i+=2;
        }
    }
    if(amount)  printf("Total amount: $%.2f\n", amount);    //打印最后一个客户总费用
    return 0;
}

/*测试数据
10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
5
aaa 01:01:10:03 off-line
aaa 01:02:00:01 on-line
CYLL 01:01:09:10 on-line
aaa 01:05:02:24 on-line
aaa 01:06:02:26 off-line

//对应输出结果
aaa 01
05:02:24 06:02:26 1442 $213.20
Total amount: $213.20
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值