1016.Phone Bills (25)...to be continued...

本文介绍了一种解决PAT AL 1016电话账单问题的算法实现,通过记录用户的通话时间和费用,计算每位用户的总通话时长及费用。采用C++实现,并使用自定义排序和遍历等技术来处理数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1016.Phone Bills (25)…to be continued…

pat-al-1016

2017-02-16

  • 坑见注释
  • 参考:《算法笔记:上机训练实战指南》机械工业出版社
/**
 * pat-al-1016
 * 2017-02-16
 * Cpp version
 * Author: fengLian_s
 */
 #include<stdio.h>
 #include<algorithm>
 #include<string.h>
 #define MAX 1010
 using namespace std;
 struct RECORD
 {
   char name[25];
   int month;
   int dd, hh, mm;
   bool flagOn;//false为off,true为on
 }record[MAX], tmp;
 int cost[25];
 bool cmp(RECORD a, RECORD b)
 {
   if(strcmp(a.name, b.name) != 0)
     return strcmp(a.name, b.name) < 0;//坑,注意要用strcmp
   else if(a.dd != b.dd)
     return a.dd < b.dd;
   else if(a.hh != b.hh)
     return a.hh < b.hh;
   else if(a.mm != b.mm)
     return a.mm < b.mm;
 }
 void getAns(int on, int off, int& lastTime, double& money)
 {
   tmp = record[on];
   while(tmp.dd < record[off].dd || tmp.hh < record[off].hh || tmp.mm < record[off].mm)
   {
     lastTime++;
     money += cost[tmp.hh];
     tmp.mm++;
     if(tmp.mm == 60)
     {
       tmp.mm = 0;
       tmp.hh++;
     }
     if(tmp.hh == 24)
     {
       tmp.hh = 0;
       tmp.dd++;
     }
   }
 }
 int main()
 {
   freopen("in.txt", "r", stdin);
   int n;
   for(int i = 0;i < 24;i++)
   {
     scanf("%d", &cost[i]);
   }
   scanf("%d", &n);
   for(int i = 0;i < n;i++)
   {
     char tmpFlag[10];
     scanf("%s%d:%d:%d:%d", record[i].name, &record[i].month, &record[i].dd, &record[i].hh, &record[i].mm);
     scanf("%s", tmpFlag);
     if(tmpFlag[1] == 'f')
      record[i].flagOn = false;
     else
      record[i].flagOn = true;
   }
   sort(record, record+n, cmp);
  //  for(int i = 0;i < n;i++)
  //  {
  //    printf("%s %d:%d:%d:%d %d\n", record[i].name, record[i].month, record[i].dd, record[i].hh, record[i].mm, record[i].flagOn);
  //  }
   int on = 0, off, next;
   while(on < n)
   {
     next = on;
     int flagPrint = 0;
     while(next < n && strcmp(record[on].name, record[next].name) == 0)
     {
       if(flagPrint == 0 && record[next].flagOn == true)//一开始对这一对判断有点疑问,比如true和false之间又隔了一个true呢?思考后发现如果又隔了一个true就相当于是认为第二个true才是这一对的开始,是不影响结果的,好奇妙啊
        flagPrint = 1;
       else if(flagPrint == 1 && record[next].flagOn == false)
        flagPrint = 2;
       next++;
     }
     if(flagPrint < 2)
     {
       on = next;
       continue;
     }
     printf("%s %02d\n", record[on].name, record[on].month);
     double sumOfMoney = 0;
     while(on < next)
     {
       while(on + 1 < next && !(record[on].flagOn == true && record[on+1].flagOn == false))
       {
         on++;
       }
       off = on+1;
       if(off == next)//坑:不要漏了这个判断
       {
         on = next;
         break;
       }
       printf("%02d:%02d:%02d ", record[on].dd, record[on].hh, record[on].mm);
       printf("%02d:%02d:%02d ", record[off].dd, record[off].hh, record[off].mm);
       int lastTime = 0;
       double money = 0;
       getAns(on, off, lastTime, money);
       printf("%d $%.2lf\n", lastTime, money/100);
       sumOfMoney += money;
       on += 2;
     }
     printf("Total amount: $%.2lf\n", sumOfMoney/100);
   }
   return 0;
 }

-TBC-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值