一、题目概述&样例
Sample Input:
10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
10
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYJJ 01:01:07:00 off-line
CYLL 01:01:08:03 off-line
CYJJ 01:01:05:59 on-line
aaa 01:01:01:03 on-line
aaa 01:02:00:01 on-line
CYLL 01:28:15:41 on-line
aaa 01:05:02:24 on-line
aaa 01:04:23:59 off-line
Sample Output:
CYJJ 01
01:05:59 01:07:00 61 $12.10
Total amount: $12.10
CYLL 01
01:06:01 01:08:03 122 $24.40
28:15:41 28:16:05 24 $3.85
Total amount: $28.25
aaa 01
02:00:01 04:23:59 4318 $638.80
Total amount: $638.80
二、思路
测试点1、2:仅输出有消费的用户;
STEP1:预处理
建立按ID索引的map结构即每个客户建立一个结构体, 结构体含:
{ 账单月份, 通话记录表:{ 时间, 标签(online/offline) } }
typedef struct
{
int time, tag;
}item;
typedef struct
{
int mon;
vector<item> record;
}customer;
map<string, customer> rec;
其中时间不含月份, 转为分钟保存;
rec[ID].mon = mon;
temp.time = d * 24 * 60 + h * 60 + m;
temp.tag = tag == "on-line" ? 0:1;
rec[ID].record.push_back(temp);
STEP2:
由于map会自动依据ID排序, 所以直接按序遍历map;
先对该用户的通话记录按时间排序;
排序后,若有相邻记录,前一为online后一为offline,则是一条可用记录;
依次统计单次通话时长和话费;
for( auto it = rec.begin(); it != rec.end(); ++it )//遍历
{
int sum = 0;//账单总和
vector<item> temp = it->second.record;
sort( temp.begin(), temp.end(), [] ( item a, item b ) { return a.time < b.time; } );//记录排序
for( int i = 0; i < temp.size(); ++i )
{
if( i + 1 != temp.size() && temp[i].tag + 1 == temp[i + 1].tag )//可用记录
{
int toll = 0;
if( !sum )
{
cout << it->first;
printf(" %02d\n", it->second.mon);
}
printf("%02d:%02d:%02d %02d:%02d:%02d", temp[i].time / ( 24 * 60 ), ( temp[i].time / 60 ) % 24 , temp[i].time % 60, temp[i + 1].time / ( 24 * 60 ), ( temp[i + 1].time / 60 ) % 24 , temp[i + 1].time % 60);
printf(" %d", temp[i + 1].time - temp[i].time);
for( int j = temp[i].time; j < temp[i + 1].time; ++j )//话费统计
{
toll += rate[ ( j / 60 ) % 24 ];
}
printf(" $%.2f\n", toll / 100.0);
sum += toll;
++i;
}
}
if( sum )
printf("Total amount: $%.2f\n", sum / 100.0);
}
话费统计:
从接通到挂断按分钟迭代累加, ( 时间 / 60 ) % 24可得到该分钟所在的小时,以便得到相应费率;
for( int j = temp[i].time; j < temp[i + 1].time; ++j )
{
toll += rate[ ( j / 60 ) % 24 ];
}
三、代码
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct
{
int time, tag;
}item;
typedef struct
{
int mon;
vector<item> record;
}customer;
int main()
{
map<string, customer> rec;
vector<int> rate(24);
for( int i = 0; i < 24; ++i )
scanf("%d", &rate[i]);
int N;
scanf("%d", &N);
for( int i = 0, mon, d, h, m; i < N; ++i )
{
string ID, tag;
item temp;
cin >> ID;
scanf("%d:%d:%d:%d", &mon, &d, &h, &m);
cin >> tag;
rec[ID].mon = mon;
temp.time = d * 24 * 60 + h * 60 + m;
temp.tag = tag == "on-line" ? 0:1;
rec[ID].record.push_back(temp);
}
for( auto it = rec.begin(); it != rec.end(); ++it )
{
int sum = 0;
vector<item> temp = it->second.record;
sort( temp.begin(), temp.end(), [] ( item a, item b ) { return a.time < b.time; } );
for( int i = 0; i < temp.size(); ++i )
{
if( i + 1 != temp.size() && temp[i].tag + 1 == temp[i + 1].tag )
{
int toll = 0;
if( !sum )
{
cout << it->first;
printf(" %02d\n", it->second.mon);
}
printf("%02d:%02d:%02d %02d:%02d:%02d", temp[i].time / ( 24 * 60 ), ( temp[i].time / 60 ) % 24 , temp[i].time % 60, temp[i + 1].time / ( 24 * 60 ), ( temp[i + 1].time / 60 ) % 24 , temp[i + 1].time % 60);
printf(" %d", temp[i + 1].time - temp[i].time);
for( int j = temp[i].time; j < temp[i + 1].time; ++j )
{
toll += rate[ ( j / 60 ) % 24 ];
}
printf(" $%.2f\n", toll / 100.0);
sum += toll;
++i;
}
}
if( sum )
printf("Total amount: $%.2f\n", sum / 100.0);
}
}