【PAT甲级 模拟】1016 Phone Bills (25 分)

算是学到了模拟时间了

while(start.day    < end.day
   || start.hour   < end.hour 
   || start.minute < end.minute){
		// 每分钟做的事
        
        // 模拟时间
		start.minute++;
		if(temp.time.minute >= 60){
			start.minute = 0;
			start.hour++;
		}
		if(temp.time.hour >= 24){
			start.hour=0;
			start.day++;
		}
	}
#include<bits/stdc++.h>
using namespace std;

double rate[24];
int N;

struct Time{
    int month;
    int day;
    int hour;
    int minute;

    bool operator<(Time & b){ // 时间按照优先级为 月、日、时、分的顺序排序
        if(month == b.month) {
            if(day == b.day) {
                if(hour == b.hour){
                    return minute < b.minute;
                }
                return hour < b.hour;
            }
            return day < b.day;
        }
        return month < b.month;
    }
};

struct Bill{
    string name;
    Time time;
    string state;
    bool operator<(Bill &b){
        if(name == b.name)
            return time < b.time;
        return name < b.name;
    }
}bills[1001];

struct Lists{
    Time start;
    Time end;
    int minu;
    double fee;
};
map<string, vector<Lists> > L; // 创建邻接表存储每一个人的每一次通话和每一次的费用,就不用费心去控制了

void getans(int on,int off, int & ti, double & money){ // 求每个用户的每次的通话时间和费用
	Bill temp = bills[on];
    // 从通话开始一分钟一分钟地模拟到通话结束
	while(temp.time.day    < bills[off].time.day 
       || temp.time.hour   < bills[off].time.hour 
       || temp.time.minute < bills[off].time.minute)
    {
		ti++;
		money += rate[temp.time.hour];
        
        // 模拟时间
		temp.time.minute++;
		if(temp.time.minute >= 60){
			temp.time.minute = 0;
			temp.time.hour++;
		}
		if(temp.time.hour >= 24){
			temp.time.hour=0;
			temp.time.day++;
		}
	}
}

int main() {
    double onedayFee = 0.0;
    for(int i = 0;i <24;++i){
        int r;
        cin >> r;
        rate[i] = r*0.01;
    }
    cin >> N;
    for(int i = 0;i < N;++i){
        cin >> bills[i].name;
        scanf("%d:%d:%d:%d ", &bills[i].time.month, &bills[i].time.day, &bills[i].time.hour, &bills[i].time.minute);
        cin >> bills[i].state;
    }
    sort(bills, bills+N);

    for(int i = 0;i < N-1;){
        if(bills[i].name == bills[i+1].name && bills[i].state == "on-line" && bills[i+1].state == "off-line") {
            Time start = bills[i].time, end = bills[i+1].time;
            //int totalMinute = ( (end.day - start.day)*24 + end.hour - start.hour)*60 + end.minute - start.minute;
            int totalMinute = 0;
            double totalFee = 0.0;
            getans(i, i+1, totalMinute, totalFee);
            L[bills[i].name].push_back({start, end, totalMinute,totalFee}); // 存储
            i+=2;
        } else 
            i++;
    }

    for(auto i: L){
        cout << i.first << " ";
        printf("%02d\n", i.second[0].start.month);
        double totalAmount = 0.0;
        for(auto j: i.second){
            printf("%02d:%02d:%02d %02d:%02d:%02d ", j.start.day, j.start.hour, j.start.minute, j.end.day, j.end.hour, j.end.minute);
            printf("%d $%.2lf\n", j.minu, j.fee);
            totalAmount += j.fee;
        }
        printf("Total amount: $%.2lf\n", totalAmount);
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值