PAT 甲级 1016 Phone Bills

这题我只能过0号测试点和3号测试点…也不知道哪里错了…很僵
思路:
将每条记录按照名字保存下来,即生成个人记录,时间全部化成分钟,分别保存在online和offline两个数组中。对两个数组分别排序。对online数组的每一个元素,找到第一个比它大的offline时间,然后从online数组中找到最大的比该offline小的时间,然后计算话费。可能该想法有问题…我再想想反例吧…看到的大佬如果发觉错了感谢指正…pat的数据真的是完美gank我…


#include <iostream>
#include <cstdio>
#include <algorithm> 
#include <cstring>
#include <cmath>
#include <vector>
#include <queue> 
using namespace std;

struct node {
    char name[25];
    int mo;
    int oncnt = 0;
    int offcnt = 0;
    int online[1005];
    int offline[1005];
};

void solve(node t, int p[])
{
    sort(t.online, t.online + t.oncnt);
    sort(t.offline, t.offline + t.offcnt);
    bool flag[1005];
    memset(flag, 1, sizeof(flag));
    double tot = 0;
    int don, hon, mon;
    int doff, hoff, moff;
    double sum = 0;
    int time = 0;
    for (int i = 0; i < 24; i++)
    {
        sum += 1.0*p[i];
    }
    printf("%s ", t.name);
    printf("%02d\n", t.mo);
    for (int i = 0; i < t.oncnt; i++)
        for (int j = 0; j < t.offcnt; j++)
        {
            if (t.online[i] < t.offline[j] && flag[j])
            {
                while (t.online[i + 1] <= t.offline[j] && i + 1 < t.oncnt)
                {
                    i++;
                }
                time = t.offline[j] - t.online[i];
                if (time == 0) break;
                double tm = 0;
                flag[j] = 0;
                don = t.online[i] / (24 * 60) + 1;
                hon = t.online[i] / 60 % 24;
                mon = t.online[i] % 60;

                doff = t.offline[j] / (24 * 60) + 1;
                hoff = t.offline[j] / 60 % 24;
                moff = t.offline[j] % 60;

                if (don == doff)
                {
                    for (int k = hon + 1; k < hoff; k++)
                    {
                        tm += p[k] * 60;
                    }
                    if (hon == hoff)
                    {
                        tm += p[hon] * (moff - mon);
                    }
                    else
                    {
                        tm += p[hon] * (60 - mon);
                        tm += p[hoff] * moff;
                    }
                }
                else
                {
                    for (int k = don + 1; k < doff; k++)
                    {
                        tm += sum * 60;
                    }
                    for (int k = hon + 1; k < 24; k++)
                    {
                        tm += p[k] * 60;
                    }
                    tm = tm + p[hon] * (60 - mon)*1.0;
                    for (int k = 0; k < hoff; k++)
                    {
                        tm += p[k] * 60;
                    }
                    tm += p[hoff] * moff*1.0;
                }
                tot += tm;
                printf("%02d:", don);
                printf("%02d:", hon);
                printf("%02d ", mon);

                printf("%02d:", doff);
                printf("%02d:", hoff);
                printf("%02d ", moff);


                printf("%d ", time);
                printf("$%.2lf\n", tm / 100);
                break;
            }
        }
    printf("Total amount: $%.2lf\n", tot / 100);
}

bool cmp(node a, node b)
{
    int l1 = strlen(a.name);
    int l2 = strlen(b.name);
    int l = min(l1, l2);
    for (int i = 0; i < l; i++)
    {
        if (a.name[i] < b.name[i])
            return 1;
        else if (a.name[i] > b.name[i])
            return 0;
    }
    if (l1 < l2)
        return 1;
    else
        return 0;
}
node r[1005];
int main()
{
    int p[15];
    int n;
    int mo, dd, hh, mu;
    char s[15];
    char name[25];
    int cnt;
    while (~scanf("%d", &p[0]))
    {
        cnt = 0;
        for (int i = 1; i < 24; i++)
        {
            scanf("%d", &p[i]);
        }
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%s %d:%d:%d:%d %s", name, &mo, &dd, &hh, &mu, s);
            int j;
            for (j = 0; j < cnt; j++)
            {
                if (strcmp(r[j].name, name) == 0)
                {
                    if (strcmp(s, "on-line") == 0)
                    {
                        r[j].online[r[j].oncnt++] = (dd - 1) * 24 * 60 + hh * 60 + mu;
                    }
                    else
                    {
                        r[j].offline[r[j].offcnt++] = (dd - 1) * 24 * 60 + hh * 60 + mu;
                    }
                    break;
                }
            }
            if (j == cnt)
            {
                strcpy(r[cnt].name, name);
                r[cnt].mo = mo;
                if (strcmp(s, "on-line") == 0)
                {
                    r[j].online[r[j].oncnt++] = (dd - 1) * 24 * 60 + hh * 60 + mu;
                }
                else
                {
                    r[j].offline[r[j].offcnt++] = (dd - 1) * 24 * 60 + hh * 60 + mu;
                }
                cnt++;
            }
        }
        sort(r, r + cnt, cmp);
        for (int i = 0; i < cnt; i++)
        {
            solve(r[i], p);
        }
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值