PAT甲级1016Phone Bills

Posted jlyg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT甲级1016Phone Bills相关的知识,希望对你有一定的参考价值。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
#include<map>
#include<iterator>
using namespace std;

#define ONLine    ("on-line")
struct Record
{
    Record(){};
    Record(char *szName,char* szTime,char* szOnline)
    {
        bOnline = (strcmp(szOnline,ONLine)==0);
        strName = szName;
        strTime = szTime;        
    }
    string strName;
    string strTime;
    bool   bOnline;    
};
struct RecordTime
{
    string strStartTime;
    string strEndTime;
    RecordTime(string starttime,string endtime)
    {
        strStartTime = starttime;
        strEndTime = endtime;
    }    
    RecordTime(){}
};
struct MyTime
{
    MyTime(){};
    MyTime(const char *cTime)
    {
        dd = 10*(cTime[0]-0)+(cTime[1]-0);
        hh = 10*(cTime[3]-0)+(cTime[4]-0);
        mm = 10*(cTime[6]-0)+(cTime[7]-0);
        iTick = dd*24*60+hh*60+mm;    
    }
    int dd;
    int hh;
    int mm;    
    int iTick;
};
int iPrice[24];
map<string,int> mapRecord;
vector<Record> vcRecord[1010]; 
vector<RecordTime> vcDisplay[1010];
bool Comp(const Record& r1,const Record& r2)
{
    return r1.strTime.compare(r2.strTime)<0;
}
int getOneDayBill()
{
    int iSum = 0;
    for(int i=0;i<24;++i)
        iSum += (60*iPrice[i]);
    return iSum;    
}
float DisplayOneCall(const RecordTime &rt)
{
    string outStartTime = rt.strStartTime.substr(3,8);
    string outEndTime = rt.strEndTime.substr(3,8);
    printf("%s %s ",outStartTime.c_str(),outEndTime.c_str());
    MyTime mtime1(outStartTime.c_str()),mtime2(outEndTime.c_str());
    int iTotalTime = mtime2.iTick - mtime1.iTick;
    float fTatalBill = 0.0f;
    
    //计算账单,用每一分钟遍历,可以AC 
    /*for(int dd=mtime1.dd,hh=mtime1.hh,mm=mtime1.mm;
        !(dd==mtime2.dd&&hh==mtime2.hh&&mm==mtime2.mm);)
    {
        fTatalBill += iPrice[hh];
        if(++mm == 60)
        {
            mm = 0;
            ++hh;
        }        
        if(hh == 24)
        {
            hh = 0;
            ++dd;
        }
    }
    */
    //把中间几个整天提出来,然后剩余的按分钟遍历,可以AC 
    /*int iDay = iTotalTime/60/24;
    fTatalBill += iDay*getOneDayBill();
    for(int hh=mtime1.hh,mm=mtime1.mm;
        !(hh==mtime2.hh&&mm==mtime2.mm);)
    {
        fTatalBill += iPrice[hh];
        if(++mm == 60)    mm = 0,++hh;
        if(hh == 24)    hh = 0;
    }
    */
    
    int iDay = iTotalTime/60/24;
    fTatalBill += iDay*getOneDayBill();
    if((mtime1.hh > mtime2.hh) 
        || (mtime1.hh == mtime2.hh&&(mtime1.mm> mtime2.mm)))
        mtime2.hh += 24;
    if(mtime1.hh == mtime2.hh && mtime2.mm>mtime1.mm)
        fTatalBill += iPrice[mtime1.hh]*(mtime2.mm-mtime1.mm);
    else
        for(int hh = mtime1.hh;hh<=mtime2.hh;++hh)
        {
            if(hh == mtime1.hh)
               fTatalBill += iPrice[hh%24]*(60-mtime1.mm);
            else if(hh == mtime2.hh)
               fTatalBill += iPrice[hh%24]*(mtime2.mm);
            else
               fTatalBill += iPrice[hh%24]*(60);    
        }
    fTatalBill = 1.0*fTatalBill/100;
    printf("%d $%.2f
",iTotalTime,fTatalBill);
    return fTatalBill;
}
int main()
{
    for(int i=0;i<24;++i)
        scanf("%d",&iPrice[i]);
    int n;
    scanf("%d",&n);
    int cnt=0;
    for(int i=0;i<n;++i)
    {
        char szName[30],szTime[30],szOnline[30];
        scanf("%s%s%s",szName,szTime,szOnline);
        Record record(szName,szTime,szOnline);
        if(mapRecord.find(szName)==mapRecord.end())
        {
            mapRecord[szName] = cnt++;
        }
        vcRecord[mapRecord[szName]].push_back(record);
    }
    for(int i=0;i<cnt;++i)
    {
        sort(vcRecord[i].begin(),vcRecord[i].end(),Comp);
        int iFindOnLine = -1;
        for(int j=0;j<vcRecord[i].size();++j)
        {
            if(vcRecord[i][j].bOnline==false && iFindOnLine != -1)
            {
                RecordTime rt(vcRecord[i][iFindOnLine].strTime,
                    vcRecord[i][j].strTime);
                vcDisplay[i].push_back(rt);
                iFindOnLine = -1;
            }    
            else if(vcRecord[i][j].bOnline)
            {
                iFindOnLine = j;
            }
        }    
    }

    map<string,int>::iterator it = mapRecord.begin();
    for(;it != mapRecord.end();it++)
    {
        int i = it->second;
        if(vcDisplay[i].size()> 0)
        {
            string strYue = vcRecord[i][0].strTime.substr(0,2);
            printf("%s %s
",it->first.c_str(),strYue.c_str());
            float fSum = 0;
            for(int j=0;j<vcDisplay[i].size();++j)
                fSum +=DisplayOneCall(vcDisplay[i][j]);
            printf("Total amount: $%.2f
",fSum);
        }
        else
        {
            
        }
    }
    
    return 0;
}

 

以上是关于PAT甲级1016Phone Bills的主要内容,如果未能解决你的问题,请参考以下文章

PAT 甲级 1016 Phone Bills (25 分) (结构体排序,模拟题,巧妙算时间,坑点太多,debug了好久)

PAT 1016. Phone Bills

1016. Phone Bills (25)——PAT (Advanced Level) Practise

PAT 1016 Phone Bills

PAT (Advanced Level) 1016 Phone Bills

PAT(A) 1016. Phone Bills (25)