1016 Phone Bills (25分)

题目大意:给出一天24个时间段的电话收费安排(美分/每小时),再给出n条电话记录,每条记录包含该记录的用户姓名、时间和状态(on-line与off-line),求每个用户该月需要缴纳多少话费。

思路:

  1. 首先将n条电话记录按照用户姓名的字母序递增,时间递增进行排序。
  2. 对于同一用户,记录其每一对相邻且状态匹配的记录(即两条记录时间上是紧挨着,同时前一条记录状态为on-line,后一条记录状态为off-line)。
  3. 对于每个用户计算其通话时长和通话费用。对于计算两个时间之间的花费,可以转化为两个时间相对于0时刻花费的差。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

const int N=1e3+5;

struct Node{
    string name,kind;
    int mon,d,h,m;
} cust[N];
int tol[24],tolsum=0;
vector<Node> v[N];
map<string,int> mp;

bool cmp(const Node &a,const Node &b){
    if(a.name==b.name){
        if(a.d==b.d){
            if(a.h==b.h) return a.m<b.m;
            return a.h<b.h;
        }
        return a.d<b.d;
    }
    return a.name<b.name;
}

int getmon(int d,int h,int m){
    int res=0;
    res=tolsum*d*60+tol[h]*m;
    for(int i=0;i<h;i++)
        res+=tol[i]*60;
    return res;
}

int gettim(int d2,int h2,int m2,int d1,int h1,int m1){
    int difm,difh,difd;
    difm=(m2-m1+60)%60;
    if(m2<m1) h2--;
    difh=(h2-h1+24)%24;
    if(h2<h1) d2--;
    difd=d2-d1;
    return difd*24*60+difh*60+difm;
}

int main()
{
    int n;
    for(int i=0;i<24;i++){
        scanf("%d",&tol[i]);
        tolsum+=tol[i];
    }

    scanf("%d",&n);
    for(int i=0;i<n;i++){
        cin>>cust[i].name;
        scanf("%d:%d:%d:%d",&cust[i].mon,&cust[i].d,&cust[i].h,&cust[i].m);
        cin>>cust[i].kind;
    }

    sort(cust,cust+n,cmp);

    int cnt=1;
    for(int i=1;i<n;i++)
        if(cust[i].name==cust[i-1].name&&cust[i].kind=="off-line"&&cust[i-1].kind=="on-line"){
            if(mp[cust[i].name]==0) mp[cust[i].name]=cnt++;
            v[mp[cust[i].name]].push_back(cust[i-1]);
            v[mp[cust[i].name]].push_back(cust[i]);
        }

    for(int i=1;i<cnt;i++){
        printf("%s %02d\n",v[i][0].name.c_str(),v[i][0].mon);
        int total=0;
        for(int j=0;j<(int)v[i].size();j+=2){
            int time=gettim(v[i][j+1].d,v[i][j+1].h,v[i][j+1].m,v[i][j].d,v[i][j].h,v[i][j].m);
            int cost=getmon(v[i][j+1].d,v[i][j+1].h,v[i][j+1].m)-getmon(v[i][j].d,v[i][j].h,v[i][j].m);
            printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2lf\n",v[i][j].d,v[i][j].h,v[i][j].m,v[i][j+1].d,v[i][j+1].h,v[i][j+1].m,time,cost/100.0);
            total+=cost;
        }
        printf("Total amount: $%.2lf\n",total/100.0);
    }

    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值