此题两次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;
}