题目大意:给定一天 24 小时的话费价格(注意给定的是一个小时内每分钟的价钱,美分计);然后给出 N 组用户通话记录(包括用户名、通话的时间日期、该时间段通话的状态),每个人的所有记录确保在同一个月内;输出每个人(按照用户名的字母顺序)的月账单,注意筛选规则(大致看样例):1.相邻时间段的“on-line”与“off-line”对应。2.最重要的一点是 如果某用户没有符合 1 条件的通话记录,则不输出用户的任何信息(否则测试组 2 、3 是没法通过的)。
注: 题目中 "It is guaranteed that at least one call is well paired in the input. "并没有保证每个用户都匹配成功,只是说所有用户中至少有一对是符合题意的。这很关键
解题思路:本题就是对数据的处理,相信看清了题目所要求的的细节,借助 C++ 强大的 stl (map、vector的使用),可以很快解决问题。
题目链接:https://www.patest.cn/contests/pat-a-practise/1016
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
using namespace std;
typedef struct Info{
int month,day,hour,minute;
string name;
int time;
int state;
}Info;//用户信息
map<string,int> NameToNum;
map<int,string> NumToName;
vector<Info> info[1005];//用户信息存入
int fee[24];
//对信息进行排序
bool cmp(Info I1,Info I2)
{
if(I1.time < I2.time)
return true;
return false;
}
int main(int argc, char** argv) {
for(int i=0;i<24;++i)
{
int temp;
cin >> temp;
fee[i] = temp;//记录时段费用
}
int n;
string NameOrder[1005];//记录各用户名,方便字母顺序排序
cin >> n;
int pos = 0;
for(int i=0;i<n;++i)
{
string name,state;;
int month,day,h,m;
cin >> name;
scanf("%d:%d:%d:%d",&month,&day,&h,&m);
cin >> state;
if(NameToNum.count(name) == 0)
{
NameOrder[pos] = name;
NameToNum[name] = pos;//编号和用户名对应
NumToName[pos++] = name;
}
Info tmp;
tmp.month = month;
tmp.day = day;
tmp.hour = h;
tmp.minute = m;
tmp.name = name;
tmp.time = day*24*60+h*60+m;
if(state == "on-line")
tmp.state = 0;
else
tmp.state = 1;
info[NameToNum[name]].push_back(tmp);
}
sort(NameOrder,NameOrder+pos);
for(int i=0;i<pos;++i)
sort(info[i].begin(),info[i].end(),cmp);//单一用户名进行时间排序
for(int i=0;i<pos;++i)
{
double sum = 0;
int id = NameToNum[NameOrder[i]];
vector<Info>::iterator it = info[id].begin();
int flag = 0;
for(;it != info[id].end();++it)
{
if(it->state == 0 && (it+1) != info[id].end() && (it+1)->state ==1)
{
flag = 1;//判断是否有有效通话时间段,如果没有,则什么也不输出
}
}
if(flag == 0)
continue;
//输出用户信息
it = info[id].begin();
cout << NameOrder[i] ;//<< info[id].;
printf(" %02d\n",it->month);
for(;it != info[id].end();++it)
{
double sum1 = 0;
//满足用户通话需求
if(it->state == 0 && (it+1) != info[id].end() && (it+1)->state ==1)
{
printf("%02d:%02d:%02d ",it->day,it->hour,it->minute);
printf("%02d:%02d:%02d ",(it+1)->day,(it+1)->hour,(it+1)->minute);
int tol = (it+1)->time - it->time;
printf("%d ",tol);
int h = it->hour;
int m = it->minute;
//模拟时间,计算费用
while(1)
{
sum1 += fee[h];
//cout<<h<<endl;
if(m == 59)
{
m = 0;
if(h == 23)
h = 0;
else
++h;
}
else
m++;
if(--tol == 0)
break;
}
sum += sum1;
printf("$%.2f\n",sum1/100.0);
}
}
printf("Total amount: $%.2f\n",sum/100.0);
}
return 0;
}