我之所以直接把代码贴上来,而没有太多解释,不是为了解析这道题目,而是为了方便我以后自己查看。
这道题花了两个小时都没做出来,最后看了答案才知道,可以用map与向量的映射,这是第一次用,所以学到了。其次是不知道怎么算时间的差值和根据每个阶段的费用求结果。
方法有2:
1.直接求起始日期时间与终止日期的差值
2.求当前日期与每月1号的相对差值,然后两个日期的相对差值相减就是绝对差值
while(start.day < end.day || start.hour < end.hour || start.min < start.min){
start.min++;
if(start.min == 60){
start.min = 0;
start.hour++;
}
if(start.hour == 24){
start.hour=0;
start.day++;
}
}
#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
const int maxn=1005;
int toll[25]={0};
struct node{
string name;
int mon,day,hou,min,time,state; //记录登入登出时间
};
bool cmp(node a,node b){
return a.name != b.name?a.name < b.name: a.time < b.time;
}
//每个通话记录的相对开销
double start(node &call){
double total=toll[call.hou]*call.min + call.day*60*toll[24];
for(int i=0;i<call.hou;i++){
total+=toll[i]*60;
}
return total/100.0;
}
int main(){
for(int i=0;i<24;i++){
scanf("%d",&toll[i]);
toll[24] += toll[i];
}
int n;
scanf("%d",&n);
vector<node> Node(n);
for(int i=0;i<n;i++){
cin >> Node[i].name;
scanf("%d:%d:%d:%d",&Node[i].mon,&Node[i].day,&Node[i].hou,&Node[i].min);
string temp;
cin >> temp;
Node[i].state = (temp =="on-line")?1:0;
//把时间转化为分钟
Node[i].time =Node[i].day*24*60 + Node[i].hou*60 + Node[i].min;
}
sort(Node.begin(),Node.end(),cmp);
map<string,vector<node> > mp; //存名字与向量对照关系
for(int i=1;i<n;i++){ //把同名的人 且满足电话通信关系的 存入一个向量中
if(Node[i].name == Node[i-1].name && Node[i-1].state == 1 && Node[i].state==0){
mp[Node[i-1].name].push_back(Node[i-1]);
mp[Node[i].name].push_back(Node[i]);
}
}
map<string,vector<node> >::iterator it;
for(it=mp.begin();it!=mp.end();it++){
vector<node> tmp = it->second;
cout<<it->first;
printf(" %02d\n",tmp[0].mon);
double total=0;
for(int i=0;i<tmp.size();i+=2){
double t =start(tmp[i+1]) - start(tmp[i]);
printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",tmp[i].day,tmp[i].hou,tmp[i].min,tmp[i+1].day,tmp[i+1].hou,tmp[i+1].min,tmp[i+1].time-tmp[i].time,t);
total+=t;
}
printf("Total amount: $%.2f\n",total);
}
return 0;
}