zoukankan      html  css  js  c++  java
  • PAT1016

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

    我的思想:将记录存入键值对map里,key为客户id,value为一个结构体数组,结构体为{时间,状态(off-line or on-line)},因为map容易是按key的升序排列,所以只要遍历map就好,先对结构体数组以time为key升序排序,保证时间的连贯性,然后找出匹配对,进行计算.. 计算麻烦点,  在一个calcu的函数里,基本思想见代码注释。个人感觉麻烦了点,但是好理解,有更好的算法希望可以讨论讨论!

    此题比较注意的地方在于:如果客户A没有合法匹配对,则什么信息都不输出

      1 #include<iostream>
      2 #include<string>
      3 #include<map>
      4 #include<vector> 
      5 #include<iterator>
      6 #include<algorithm>
      7 #include<iomanip>
      8  using namespace std;
      9 
     10  struct Node
     11  {
     12      string time;
     13      string status;
     14      /*time记录时间,status记录off-line, on-line*/
     15  };
     16 
     17  /*计算时间及其费用*/
     18  int calcu(string start, string end, vector<double> &toll, double &cost)
     19  {
     20      int dd(0), hh(0), mm(0);
     21      int sh, sm;
     22      for(int i=0; i<3; ++i)
     23          if(i == 0)     
     24          { 
     25              sm = (start[9]-'0')*10 + (start[10]-'0');
     26              mm = (end[9]-start[9])*10 + (end[10]-start[10]);
     27              if(mm < 0 )
     28              {--hh; mm+=60;}
     29          }
     30          else if(i == 1)
     31          {
     32              sh = (start[6]-'0')*10 + (start[7]-'0');
     33              hh += (end[6]-start[6])*10 + (end[7]-start[7]);
     34              if(hh < 0)
     35                  {--dd; hh+=24;}        
     36          }
     37          else
     38              dd +=  (end[3]-start[3])*10 + (end[4]-start[4]);
     39     /*两天之间差的时间*/
     40     int minutes = dd*24*60+hh*60+mm;
     41     int val = minutes;
     42     int hour=sh;
     43     if(sm != 0)
     44     {
     45         sm = 60-sm;
     46         if(minutes > sm)
     47             cost = toll[sh]*sm;
     48         else
     49             cost = toll[sh]*minutes;
     50         /*注意此判断!*/
     51         minutes -=sm;
     52         ++hour;
     53     }
     54     /*将开始时间补全到整点并计算相应费用,后面的while循环用于计算每过60分钟,费用的总和*/
     55     while(minutes > 0)
     56     {
     57         if(minutes < 60)
     58         {
     59             cost += toll[hour%24]*minutes;
     60             minutes = -1;
     61         }
     62         else
     63         {
     64             minutes -= 60;
     65             cost += toll[hour%24]*60;
     66             ++hour;
     67         }
     68     }
     69     return val;
     70  }
     71 
     72  /*判断用户记录是否有合法匹配对,也是本题坑的地方*/
     73  bool legal(vector<Node> &temp)
     74  {
     75      for(int i=0; i<temp.size()-1; ++i)
     76         if(temp[i].status == "on-line" && temp[i+1].status == "off-line")
     77             return true;
     78     return false;         
     79  }
     80 
     81  bool comp(Node n1, Node n2)
     82  {
     83      if(n1.time < n2.time)
     84          return true;
     85      else
     86          return false;
     87  }
     88 
     89  int main()
     90  {
     91      int in;
     92      while(cin>>in)
     93      {
     94          vector<double> toll(24,0); toll[0]=in;
     95          for(int i=1; i<24; ++i)
     96              cin>>toll[i];
     97          int N; cin>>N;
     98         map<string, vector<Node>> record;
     99         for(int i=0; i<N; ++i)
    100         {
    101             string id, t, s;
    102             cin>>id>>t>>s;
    103             Node n={t, s};
    104             record[id].push_back(n);
    105             /*记录存入键值对里key为客户id,value为Node*/
    106         }
    107         map<string, vector<Node>>::iterator iter = record.begin();
    108         string month(iter->second.begin()->time, 0, 2);
    109         /*记录月份*/
    110         for(; iter != record.end(); ++iter)
    111         {
    112             sort(iter->second.begin(), iter->second.end(), comp);
    113             vector<Node> temp = iter->second;
    114             if(legal(temp))/*是否有合法匹配对*/
    115             {
    116                 cout<<iter->first<<" "<<month<<endl;
    117                 double sum(0);
    118                 for(int i=0; i<temp.size()-1; ++i)
    119                 {
    120                     if(temp[i].status == "on-line" && temp[i+1].status == "off-line")
    121                     {
    122                         double cost(0);
    123                         int minu = calcu(temp[i].time, temp[i+1].time, toll, cost);
    124                         sum += cost;
    125                         string s(temp[i].time, 3, 8);
    126                         string e(temp[i+1].time, 3, 8);
    127                         cout<<s<<" "<<e<<" "<<minu<<" "<<"$"<<fixed<<setprecision(2)<<cost/100<<endl;
    128                     }
    129                 }
    130                 cout<<"Total amount: $"<<fixed<<setprecision(2)<<sum/100<<endl;
    131             }
    132         }
    133      }
    134      return 0;
    135  }
  • 相关阅读:
    JavaScript经典效果集锦之五(转)
    消息队列函数
    ipcs查看消息队列命令
    sizeof的解析
    【转】使用Reporting Services制做可折叠的报表
    【转】Hibernate动态条件查询(Criteria Query)
    【Wonder原创】NHibernate调用存储过程
    【转】C# const和readonly的区别
    【转】人际关系经验
    winform只存在一个进程处理
  • 原文地址:https://www.cnblogs.com/bochen-sam/p/3352304.html
Copyright © 2011-2022 走看看