PAT 1016 Phone Bills (25 分)

PAT 1016 Phone Bills

今天给大家分享一道PAT甲级的小题,考察点: 模拟

原题请点击我

简单翻译:

先输入24个价格,第i个表示一天中的第i小时打电话是多少美分一分钟

再输入一个N,表示在线电话记录的个数

下面N行数据,每行包括一个电话记录,字段包括:

名字 - 时间(MM:dd:HH:mm) - 状态(on-line / off-line)

给每个有完整通话记录的用户打印自己的账单。格式如下所示:

姓名 月份
开始时间 结束时间 消费金额

总消费


思路:

这个题目,真的把真实场景给模拟的透透的,(其实他还做了简化,因为规定说只能在一个月里,如果加上月份,每个月还有28天,29天,30天,31天,会更难搞(我太菜了…))

  • 先对得到的数据进行整理和排序,第一关键字是用户名,第二关键字是时间。
  • 排序完之后就模拟一下即可,注意一点就是状态的判断,只有先on-line之后在off-line才算完整的一次通话。
  • 最后就是计算消费的时候,可以不用模拟,而是直接暴力循环算消费,这样会少很多思考量(我太菜了对不起)。

cpp代码:

#include<bits/stdc++.h>
#define ll long long int
#define vi vector<int>
#define vvi vector<vector<int>>
#define fastio ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define INF (1e9)
#define all(x) x.begin(), x.end()
#define len(x) x.size()
#define pb(x) push_back(x)
using namespace std;

struct node {
    string name;
    int time, type;
}node[1001];
int cost[24];
int totalCost;
void f(int startTime, int endTime) {
	ll costs = 0;
	ll dayCost = 0;
	for (int i = 0; i < 24; i++) 
		dayCost += cost[i] * 60;
		
	int day1 = startTime / 1440 + 1;
    int hour1 = (startTime - 1440 * (day1 - 1)) / 60;
    int m1 = startTime - (day1 - 1) * 1440 - hour1 * 60;
    	
    printf("%02d:%02d:%02d ", day1, hour1, m1);
    int day2 = endTime / 1440 + 1;
    int hour2 = (endTime - 1440 * (day2 - 1)) / 60;
    int m2 = endTime - (day2 - 1) * 1440 - hour2 * 60;
    printf("%02d:%02d:%02d %d $", day2, hour2, m2, endTime - startTime);

    for (int i = 0; i < endTime - startTime; i++) {
        m1++;
        costs += cost[hour1];
        if (m1 == 60) {
            hour1++;
            m1 = 0;
            if (hour1 == 24) {
                day1++;
                hour1 = 0;
            }
        }
    }
    printf("%.2lf\n", costs / 100.0);
    totalCost += costs;
}

int main() {
    //fastio;
    totalCost = 0;
    for (int i = 0; i < 24; i++) scanf("%d", &cost[i]);
    int n;
    scanf("%d", &n);
    int month;
    for (int i = 0; i < n; i++) {
        string type;
        int day, hour, m;
        cin >> node[i].name;
        scanf("%d:%d:%d:%d", &month, &day, &hour, &m);
        cin >> type;
        node[i].time = (day - 1) * 1440 + hour * 60 + m;
        node[i].type = (type == "off-line" ? 0 : 1);
    }
    
    sort(node, node + n, [&](const struct node& a, const struct node & b)->bool{
                if (a.name != b.name) return a.name < b.name;
                return a.time < b.time;
            });
    string name = "";
    bool flag = false;
    int startTime = -1, endTime = -1;
    for (int i = 0; i < n; i++) {
        if (node[i].name != name) {
            name = node[i].name;
            startTime = -1;
            endTime = -1;
            if (totalCost != 0) {
            	printf("Total amount: $%.2lf\n", totalCost / 100.0);
                totalCost = 0;
            }
            flag = false;
        }
        if (node[i].type == 1) {
            startTime = node[i].time;
        }
        if (node[i].type == 0 && startTime != -1) {
            endTime = node[i].time;
            if (!flag) { cout << name; printf(" %02d\n", month); flag = true;}
            f(startTime, endTime);
            endTime = -1;
            startTime = -1;            
        }
    }
    if (totalCost != 0) {
        printf("Total amount: $%.2lf\n", totalCost / 100.0);
        totalCost = 0;
    }
    return 0;
}

点我看PAT甲级全部题解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值