zoukankan      html  css  js  c++  java
  • Phone Bills【PAT 1016题】 电话账单结算

    题目链接:http://pat.zju.edu.cn/contests/pat-practise/1016

    以前在POJ上也见过类似的题,当时还不会qsort,菜的一米,遇到大数据还用链表做,还没等把输入处理完成,就已经头大的发麻了,看来我还是有一点进步的。

    这道题我开了个record数组,记录所有的账单,第一步先根据字母表顺序将账单排序分类,在此要大大的感谢一把qsort,它可以数组内指定位置和指定长度进行排序,所以我就没有把账单记录分开存到各个客户名下,而是用qsort分割排序,和单独处理单个客户的账单效果一模一样。第二步,根据客户名称作为id,单独对当前处理的客户记录进行时间排序,然后处理,这道题逻辑有点小复杂,和昨天的那个银行排队一样,都属于无关算法而着重逻辑的,到最后的计算时间和费用有点棘手,不过把思路整清楚就OK了。

    这道题要注意的陷阱就一点:1.如果客户A的账单记录没有任何一对是合法的,则客户A什么信息都不输出,估计电信局就这样设计的,一年应该可以省不少木材。^_^

      1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4
    5 typedef struct
    6 {
    7 char name[22];//名字
    8 int month;//月份
    9 int day;//
    10 int hour;//
    11 int minute;//
    12 char tag[10];//on-line or off-line
    13 }record;
    14
    15 int n;
    16 record *rd;
    17 int rate[24];//费率
    18 int count, start;//记录当前处理的这个用户的记录数目,和当前这个用户的第一条记录位置
    19 double totalCharge;//该用户该月的费用合计
    20
    21 double charge(int sday, int shour, int sminute, int eday, int ehour, int eminute)//计算一条有效电话记录的时长和费用,并返回费用
    22 {
    23 double cost = 0;
    24 long time = 0;
    25
    26 while(sday < eday)//先让天相等
    27 {
    28 time += (60 - sminute);
    29 cost += (60 - sminute) * rate[shour];
    30 sminute = 0; shour ++;//分化成0,时加1
    31 time += 60 * (24 - shour);
    32 while(shour < 24)
    33 {
    34 cost += 60 * rate[shour];
    35 shour ++;
    36 }
    37 shour = 0; sday ++;//时化成0,天加1
    38 }//天此时相等,时分为00:00
    39 while(shour < ehour)//再让时相等
    40 {
    41 time += (60 - sminute);
    42 cost += (60 - sminute) * rate[shour];
    43 sminute = 0; shour ++;
    44 }
    45 time += (eminute - sminute);
    46 cost += rate[ehour] * (eminute - sminute);
    47
    48 printf("%ld $%.2lf\n", time, cost / 100);
    49
    50 return cost / 100;
    51 }
    52
    53 void totalCount()//数出当前要处理的客户的总记录数目
    54 {
    55 int i;
    56 for(i = start + 1; i < n; i ++)
    57 {
    58 if(strcmp(rd[i].name, rd[i - 1].name) != 0)
    59 {
    60 break;
    61 }
    62 else
    63 {
    64 count ++;
    65 }
    66 }
    67 }
    68
    69 int comp_name(const void *a, const void *b)
    70 {
    71 record c = *(record *)a;
    72 record d = *(record *)b;
    73
    74
    75 if(strcmp(c.name, d.name) <= 0) return -1;
    76 else return 1;
    77 }
    78
    79 int comp_time(const void *a, const void *b)
    80 {
    81 record c = *(record *)a;
    82 record d = *(record *)b;
    83
    84 if(c.day < d.day) return -1;
    85 else if(c.day > d.day) return 1;
    86 else
    87 {
    88 if(c.hour < d.hour) return -1;
    89 else if(c.hour > d.hour) return 1;
    90 else
    91 {
    92 if(c.minute < d.minute) return -1;
    93 else return 1;
    94 }
    95 }
    96 }
    97
    98 int main()
    99 {
    100 int i;
    101 int flag;//1应该出现offline, 0应该出现online
    102 int onpos;//记录最近有效的on-line记录位置,为了算出charge
    103 int sign;//0表示该客户名字和月份还没有输出,1表示已输出
    104
    105
    106 while(scanf("%d", &rate[0]) != EOF)
    107 {
    108 for(i = 1; i < 24; i ++)
    109 {
    110 scanf("%d", &rate[i]);
    111 }
    112 scanf("%d", &n);
    113 rd = (record *)malloc(n * sizeof(record));
    114 for(i = 0; i < n; i ++)
    115 {
    116 scanf("\n%s %d:%d:%d:%d %s", rd[i].name, &rd[i].month, &rd[i].day, &rd[i].hour, &rd[i].minute, rd[i].tag);
    117 }
    118 qsort(rd, n, sizeof(record), comp_name);//先将记录按字母表顺序分类
    119 count = 1; start = 0; totalCount(); sign = 0;
    120 while(start < n)//整个记录表还没处理完
    121 {
    122 qsort(rd + start, count, sizeof(record), comp_time);
    123 flag = 0;
    124 totalCharge = 0;
    125 for(i = start; i < start + count; i ++)//处理该客户
    126 {
    127 if(flag == 0)//期待出现online,如果是offline跳过
    128 {
    129 if(rd[i].tag[1] == 'f')//off-line
    130 {
    131 continue;
    132 }
    133 else//on-line
    134 {
    135 onpos = i;
    136 flag = 1;
    137 }
    138 }
    139 else//期待出现offline,如果是online则更新onpos
    140 {
    141 if(rd[i].tag[1] == 'n')//on-line
    142 {
    143 onpos = i;
    144 }
    145 else//off-line
    146 {
    147 if(sign == 0)
    148 {
    149 printf("%s %02d\n", rd[start].name, rd[start].month);
    150 sign = 1;
    151 }
    152 printf("%02d:%02d:%02d %02d:%02d:%02d ", rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute);
    153 totalCharge += charge(rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute);
    154 flag = 0;
    155 }
    156 }
    157 }
    158 if(sign == 1)
    159 {
    160 printf("Total amount: $%.2lf\n", totalCharge);
    161 }
    162 start += count; count = 1; totalCount(); sign = 0;
    163 }
    164 }
    165 return 0;
    166 }



  • 相关阅读:
    各种犯下的错误(2)
    c3p0封装
    servlet模板
    各种犯下的错误(1)
    连接池的创建与封装
    jdbc连接用工具类
    Java从入门到入坟(1)
    小米商城网页版(js+css)
    JavaScript学习篇(9)
    JavaScript学习篇(8)
  • 原文地址:https://www.cnblogs.com/Rafy/p/2408013.html
Copyright © 2011-2022 走看看