【PAT】1016. Phone Bills

考查点:模拟题

提交情况:第一次map写错浪费了很多时间,还有出现死循环,因为这里要遍历的是一对所以边界不是<n·而是<n-1,还有里面的坑主要是费用为零的不需要输出。。只能说题目不严谨。

思路:定义结构体,排序,用到了map把名字定义为下标,计算费用时先对时间段预处理计算到该时间段的总时间sum数组可以优化时间

#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define FOR(i, x, y) for(int i = x; i <= y; i++)
#define rFOR(i, x, y) for(int i = x; i >= y; i--)
#define MAXN 10010
#define oo 0x3f3f3f3f
using namespace std;

int sum[30];
int toll[30];
struct call{
   int mon,dd,hh,mm;
   bool st;
}tc;
map<string,int> mp;
map<int ,string> pm;
struct customer{
    vector<call> record;
    int id;
    char name[25];
}person[1010];
int num;
int total[1010];
bool cmpname(customer a,customer b)
{
    return strcmp(a.name,b.name)<0;
}
bool cmp(call a,call b)
{
    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;
}
double compute(call a,call b,int& last)
{
    double ans=0;
    if(a.dd!=b.dd){
        ans+=(b.dd-a.dd-1)*sum[24];
        ans+=sum[b.hh]+sum[24]-sum[a.hh];
        ans+=toll[b.hh+1]*b.mm-toll[a.hh+1]*a.mm;
        last+=(b.dd-a.dd-1)*24*60;
        last+=(b.hh+24-a.hh)*60;
        last+=b.mm-a.mm;
    }else{
        ans+=sum[b.hh]-sum[a.hh];
        ans+=toll[b.hh+1]*b.mm-toll[a.hh+1]*a.mm;
        last+=(b.hh-a.hh)*60;
        last+=b.mm-a.mm;
    }
    return ans;
}
int main()
{
     #ifdef LOCAL
        freopen("data.in","r",stdin);
        freopen("data.out","w",stdout);
    #endif // LOCAL

    FOR(i,1,24)
    {
        scanf("%d",&toll[i]);
        sum[i]=sum[i-1]+toll[i]*60;

    }
    int N;
    char str[10];
    scanf("%d",&N);
    char name[25];
    string sname;
    FOR(i,0,N-1)
    {

        scanf("%s %d:%d:%d:%d %s",name,&tc.mon,&tc.dd,&tc.hh,&tc.mm,str);
        if(strcmp(str,"on-line")==0)tc.st=true;
        else tc.st=false;
        sname=string(name);
        if(mp.find(sname)!=mp.end()){
            person[mp[sname]].record.push_back(tc);

        }else{

            mp[sname]=num;
            pm[num]=sname;
            strcpy(person[num].name,name);
            person[num].record.push_back(tc);
            person[num].id=num;
            num++;

        }

    }

    sort(person,person+num,cmpname);

    FOR(i,0,num-1)
    {
    //    printf("%s %02d\n",person[i].name,person[i].record[0].mon);
        sort(person[i].record.begin(),person[i].record.end(),cmp);
        int j=0;
        double tot=0;
        while(j+1<person[i].record.size())
        {
             if(person[i].record[j].st==true&&person[i].record[j+1].st==false){
                    int last=0;
                    double res=compute(person[i].record[j],person[i].record[j+1],last);
                    tot+=res;

                //    printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",person[i].record[j].dd,person[i].record[j].hh,person[i].record[j].mm,person[i].record[j+1].dd,person[i].record[j+1].hh,person[i].record[j+1].mm,last,res/100);
                    j+=2;

                }else{
                    int last=0;
                    while(person[i].record[j].st!=true&&j+1<person[i].record.size())j++;
                    if(j+1==person[i].record.size())break;
                    else{
                        int k=j+1;
                        while(k<person[i].record.size()&&person[i].record[k].st!=false)k++;
                        if(k==person[i].record.size())break;
                        else{
                            double res=compute(person[i].record[k-1],person[i].record[k],last);
                            tot+=res;
                       //     printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",person[i].record[k-1].dd,person[i].record[k-1].hh,person[i].record[k-1].mm,person[i].record[k].dd,person[i].record[k].hh,person[i].record[k].mm,last,res/100);
                            j=k+1;
                        }

                    }
                }

        }
        total[i]=tot;
      //  printf("Total amount: $%.2f\n",tot/100);
    }

    FOR(i,0,num-1)
    {
        if(total[i]){


     printf("%s %02d\n",person[i].name,person[i].record[0].mon);
        sort(person[i].record.begin(),person[i].record.end(),cmp);
        int j=0;
        double tot=0;
        while(j+1<person[i].record.size())
        {
             if(person[i].record[j].st==true&&person[i].record[j+1].st==false){
                    int last=0;
                    double res=compute(person[i].record[j],person[i].record[j+1],last);
                    tot+=res;

                  printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",person[i].record[j].dd,person[i].record[j].hh,person[i].record[j].mm,person[i].record[j+1].dd,person[i].record[j+1].hh,person[i].record[j+1].mm,last,res/100);
                    j+=2;

                }else{
                    int last=0;
                    while(person[i].record[j].st!=true&&j+1<person[i].record.size())j++;
                    if(j+1==person[i].record.size())break;
                    else{
                        int k=j+1;
                        while(k<person[i].record.size()&&person[i].record[k].st!=false)k++;
                        if(k==person[i].record.size())break;
                        else{
                            double res=compute(person[i].record[k-1],person[i].record[k],last);
                            tot+=res;
                           printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",person[i].record[k-1].dd,person[i].record[k-1].hh,person[i].record[k-1].mm,person[i].record[k].dd,person[i].record[k].hh,person[i].record[k].mm,last,res/100);
                            j=k+1;
                        }

                    }
                }

        }

       printf("Total amount: $%.2f\n",tot/100);
        }
    }

    return 0;
}
简化版
#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define FOR(i, x, y) for(int i = x; i <= y; i++)
#define rFOR(i, x, y) for(int i = x; i >= y; i--)
#define MAXN 1010
#define oo 0x3f3f3f3f
#define MT(x,i) memset(x,i,sizeof(x))
using namespace std;

int sum[35];
int toll[25];
int a[28];
int n;
map<string,int> mp;
struct person{
    int mon,hh,mm,dd;
    int flag;
    char name[25];
}stu[MAXN],valid[MAXN];

bool cmp(person a,person b)
{
    if(strcmp(a.name,b.name))return strcmp(a.name,b.name)<0;
    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()
{
     #ifdef LOCAL
        freopen("data.in","r",stdin);
        freopen("data.out","w",stdout);
    #endif // LOCAL


    FOR(i,1,24)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    scanf("%d",&n);
    FOR(i,0,n-1)
    {
        char flag[7];
        scanf("%s%d:%d:%d:%d%s",stu[i].name,&stu[i].mon,&stu[i].dd,&stu[i].hh,&stu[i].mm,flag);

        if(!strcmp("on-line",flag))stu[i].flag=1;
        else stu[i].flag=0;
    }
    sort(stu,stu+n,cmp);

    int num=0;
    FOR(i,0,n-2)
    {
        if(!strcmp(stu[i].name,stu[i+1].name)&&stu[i].flag&&!stu[i+1].flag){
            valid[num++]=stu[i];
            valid[num++]=stu[i+1];
            string name=(string)stu[i].name;
            if(mp.find(name)==mp.end())mp[name]=1;
            else mp[name]++;

        }
    }
    int now=0;
    for(int i=0;i<mp.size();i++)
    {
        printf("%s %02d\n",valid[now].name,valid[now].mon);
        string name=valid[now].name;
        double ans=0;

        for(int j=0;j<mp[name];j++){
            double tmp=0;
            tmp+=(valid[now+1].dd-valid[now].dd)*sum[24]*60;
            int hh1=valid[now+1].hh,hh2=valid[now].hh;
            tmp+=sum[hh1]*60+a[hh1+1]*valid[now+1].mm-sum[hh2]*60-a[hh2+1]*valid[now].mm;
            int last=(valid[now+1].dd-valid[now].dd)*24*60+(hh1-hh2)*60+valid[now+1].mm-valid[now].mm;
            printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",valid[now].dd,hh2,valid[now].mm,valid[now+1].dd,hh1,valid[now+1].mm,last,tmp/100);
            ans+=tmp;
            now+=2;
        }
        printf("Total amount: $%.2f\n",ans/100);

    }


    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值