PAT甲级 1016 Phone Bills (25 分)

题目:戳这里

题意:
模拟通话账单记录。
首先给出24个数表示每天的24小时,每个时间段通话的话费各是多少(注意,1美刀=100美分)。
接着给出n个记录,每个记录的内容有通话人姓名、通话时间点,是接入时间点还是挂断时间点。求每个用户的账单。
注意:
每一组样例的月份都是一样的。
通话记录只有 同一个人、时间相邻且接入在前挂断在后 时才有效。
每个人可能在账单中有多次通话记录。

解题思路:
模拟。但是我写的很麻烦,写了2个小时。

附代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;

double cost[maxn];
struct nod {
    string nam;
    int mm, dd, hh, mon;
    int tim;
    int sts;
}nu[maxn];
struct Nod{
    string nam;
    int bg;
    int ed;
    int mon, bgdd, bghh, bgmm, eddd, edhh, edmm;
}ans[maxn];

bool cmp(nod a, nod b) {
    if(a.nam == b.nam && a.tim == b.tim) return a.sts < b.sts;
    if(a.nam == b.nam) return a.tim < b.tim;
    return a.nam < b.nam;
}
double getM(int bgdd,int bghh,int bgmm,int eddd,int edhh,int edmm) {
    double moy = 0.0;
    if(bgdd == eddd) {
        if(bghh == edhh) {
            moy = cost[bghh] * (edmm - bgmm)* 1.0;
        } else {
            moy += (60.0 - bgmm) * cost[bghh];
            for(int i = bghh + 1; i < edhh; ++i) {
                moy += 60.0 * cost[i];
            }
            moy += edmm * cost[edhh];
        }
    } else {
        moy += (60.0 - bgmm) * cost[bghh];
        for(int i = bghh + 1; i < 24; ++i) {
            moy += 60.0 * cost[i];
        }
        for(int i = bgdd+1; i < eddd; ++i) {
            for(int j = 0; j < 24; ++j) {
                moy += 60.0 * cost[j];
            }
        }
        for(int i = 0; i < edhh; ++i) {
            moy += 60.0 * cost[i];
        }
        moy += edmm * cost[edhh];
    }
    return moy;
}
string st;
int main() {
    for(int i = 0; i < 24; ++i) {
        cin>>cost[i];
    }
    int n;
    cin>>n;
    for(int i = 1; i <= n; ++i) {
        cin>>nu[i].nam>>st;

        int u = 0;
        for(int j = 0; j < st.length(); j += 3) {
            int v = 0;
            v += st[j] - '0';
            v = v * 10 + st[j + 1] - '0';
            if(j == 0) u = v, nu[i].mon = v;;
            if(j == 3) u = u * 30 + v, nu[i].dd = v;
            if(j == 6) u = u * 24 + v, nu[i].hh = v;
            if(j == 9) u = u * 60 + v, nu[i].mm = v;
        }
        nu[i].tim = u;
        cin>>st;
        if(st[1] == 'n') nu[i].sts = 0;
        else nu[i].sts = 1;

    }
    sort(nu + 1, nu + 1 + n, cmp);
    int cnt = 0;
    for(int i = 1; i < n; ++i) {
        if(nu[i].nam == nu[i + 1].nam && nu[i].tim <= nu[i + 1].tim && nu[i].sts < nu[i + 1].sts) {
                ans[++cnt].nam = nu[i].nam;
                ans[cnt].bg = nu[i].tim; ans[cnt].ed = nu[i + 1].tim;
                ans[cnt].mon = nu[i].mon;
                ans[cnt].bgdd = nu[i].dd; ans[cnt].bghh = nu[i].hh; ans[cnt].bgmm = nu[i].mm;
                ans[cnt].eddd = nu[i+1].dd; ans[cnt].edhh = nu[i+1].hh; ans[cnt].edmm = nu[i+1].mm;
        }
    }
    double totMoy = 0.0;
    for(int i = 1; i <= cnt; ++i) {
        int totTim = ans[i].ed - ans[i].bg;
        double nowMoy = getM(ans[i].bgdd,ans[i].bghh,ans[i].bgmm,ans[i].eddd,ans[i].edhh,ans[i].edmm) / 100.0;
        
        if(ans[i].nam != ans[i - 1].nam) {
            cout<<ans[i].nam<<" ";
            printf("%02d\n", ans[i].mon);
        }
        printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",ans[i].bgdd, ans[i].bghh, ans[i].bgmm, ans[i].eddd, ans[i].edhh, ans[i].edmm, totTim, nowMoy);
        totMoy += nowMoy;
        if(ans[i].nam != ans[i + 1].nam) {
            printf("Total amount: $%.2f\n",totMoy);
            totMoy = 0.0;
        }

    }
	return 0;
}

/*
10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
4
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYLL 01:28:16:05 on-line
CYLL 01:28:17:41 on-line

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值