PATA1016题解

博客详细解析了PAT考试中PATA1016题目的两种不同解法,强调当个人费用为0时的特殊处理情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此题两次AC使用不同的代码

注意个人的费用为0时不必输出

//
//  main.cpp
//  PATA1016
//
//  Created by Phoenix on 2018/2/1.
//  Copyright © 2018年 Phoenix. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int toll[24];
int ans;
struct People {
    char name[25];
    int mon, dd, hh, mm;
    int status;
}peo[maxn];


//此方法计算每个时间与0:0:0的时间差与费用,再相减即可;若隔天加上一整天的时间和费用即可
int num, money;
void Money(People a, People b) {
    num = 0; money = 0;
    int d1, h1, m1, d2, h2, m2;
    d1 = a.dd; d2 = b.dd;
    h1 = a.hh; h2 = b.hh;
    m1 = a.mm; m2 = b.mm;
    if(d1 < d2){
        num += (d2 - d1) * 24 * 60;
        money += (d2 - d1) * ans * 60;
    }
    int num1 = 0, num2 = 0;
    int money1 = 0, money2 = 0;
    for(int i = 0; i < h1; i++) {
        num1 += 60;
        money1 += toll[i] * 60;
    }
    num1 += m1;
    money1 += toll[h1] * m1;
    for(int i = 0; i < h2; i++) {
        num2 += 60;
        money2 += toll[i] * 60;
    }
    num2 += m2;
    money2 += toll[h2] * m2;
    num = num + num2 - num1;
    money = money + money2 - money1;
}

//计算两个时间之差与费用的另一种方法,参考晴神宝典。
/*
void get_ans(int on,int off,int& time,int& money){
    temp=logs[on];
    while(temp.day<logs[off].day||temp.hour<logs[off].hour||temp.minute<logs[off].minute){
        time++;
        money+=toll[temp.hour];
        temp.minute++;
        if(temp.minute>=60){
            temp.minute=0;
            temp.hour++;
        }
        if(temp.hour>=24){
            temp.hour=0;
            temp.day++;
        }
    }
}
 */

bool cmp(People a, People b){
    if(strcmp(a.name, b.name) != 0) return strcmp(a.name, b.name) < 0;
    else if(a.dd != b.dd) return a.dd < b.dd;
    else if(a.hh != b.hh) return a.hh < b.hh;
    else return a.mm < b.mm;
}

int main(int argc, const char * argv[]) {
    for(int i = 0; i < 24; i++) {
        scanf("%d", &toll[i]);
        ans += toll[i];
    }
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        scanf("%s %d:%d:%d:%d", peo[i].name, &peo[i].mon, &peo[i].dd, &peo[i].hh, &peo[i].mm);
        char status[10];
        scanf("%s", status);
        if(status[1] == 'n') {
            peo[i].status = 0;
        } else {
            peo[i].status = 1;
        }
    }
    sort(peo, peo + n, cmp);
    //一下为二刷的AC代码
    int i = 0;
    bool flag = false;
    while(i < n) {
        int k = 1;
        for(int j = i + 1; j < n; j++) {    //计算该用户的记录个数与是否有有效的记录(一对记录)
            if(strcmp(peo[j].name, peo[j - 1].name) == 0){
                if(peo[j].status == 1 && peo[j - 1].status == 0) {  //有有效记录flag标记为true
                    flag = true;
                }
                k++;
            } else {
                break;
            }
        }
        //printf("%d\n", k);
        if(flag == false){          //无有效记录,跳过该用户
            i = i + k;
        } else{
            //printf("%d\n", k);
            int total = 0;
            printf("%s %02d\n", peo[i].name, peo[i].mon);
            int j = i;
            for(i; i < j + k; i++) {
                //底下的if一定要判断peo[i]与peo[i-1]是否为同一个人,一直因为这一点卡了很久。。。
                if(i > 0 && strcmp(peo[i].name,peo[i-1].name)==0 && peo[i].status == 1 && peo[i - 1].status == 0){
                    printf("%02d:%02d:%02d %02d:%02d:%02d ",peo[i-1].dd, peo[i-1].hh, peo[i-1].mm, peo[i].dd,peo[i].hh,peo[i].mm);
                    Money(peo[i-1], peo[i]);
                    total += money;
                    printf("%d $%.2f\n",num, money / 100.0);
                }
            }
            printf("Total amount: $%.2f\n", total / 100.0);
            total = 0;
            flag = false;
        }
        
    }
    //以下为一刷的时的AC代码,参考晴神宝典
    /*
    int on=0,off,next;
    while(on<n){
        int needPrint=0;
        next=on;
        while(next<n&&strcmp(peo[next].name,peo[on].name)==0){
            if(needPrint==0&&peo[next].status==0){
                needPrint=1;
            }else if(needPrint==1&&peo[next].status==1){
                needPrint=2;
            }
            next++;
        }
        if(needPrint<2){
            on=next;
            continue;
        }
        int Allmoney=0;
        printf("%s %02d\n",peo[on].name,peo[on].mon);
        while(on<next){
            while(on<next-1&&!(peo[on].status==0&&peo[on+1].status==1)){
                on++;
            }
            off=on+1;
            if(off==next){
                on=next;
                break;
            }
            printf("%02d:%02d:%02d ",peo[on].dd,peo[on].hh,peo[on].mm);
            printf("%02d:%02d:%02d ",peo[off].dd,peo[off].hh,peo[off].mm);
            Money(peo[on], peo[off]);
            Allmoney+=money;
            printf("%d $%.2f\n",num,money/100.0);
            on=off+1;
        }
        printf("Total amount: $%.2f\n",Allmoney/100.0);
    }
     */
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值