一、概述
题设太复杂,简而言之收话费。
坑点主要有以下几个:
总话费为0的话什么都不输出,就当没有这个人,我觉得这个逻辑有问题,因为题设中各小时的话费是非负数,因此可能是0,说不定电信公司善心大发呢,这样即使有有效通信话费也可能是0,但是没考虑这种情况;
输出的小数位一位时要加0,因为例子给的十分好,都是10啊5啊什么的,所以对于总话费的输出容易忘了加0,或者是像我一样对100取余,这样后面的0是保留了,但是前面的0还是没加上。这样测试点123都过不去,很亏的;
既是坑点又是难点的是话费的计算,很难想,有两种方法:其一是从打电话的一刻起一分钟一分钟加,加到挂电话的时刻;其二是打电话的时刻与00:00:00计算一个话费,挂电话的时刻也一样,因为与00:00:00相减计算话费好算一点;然后这两个的话费相减。我用了前者,优化了一下,退出循环不再是与挂电话时刻相等,而是选择利用总通话分钟数,这样就避开了对于跨天通话的计算,简单了一点。
二、分析
使用结构体储存通话记录,如下:
struct Deal
{
char name[21];
int MM;
int DD;
int hh;
int mm;
int OnorOff;
}deal[1000];
这应该是轻车熟路。
cmp函数如下:
bool cmp(Deal a, Deal b)
{
int s = strcmp(a.name, b.name);
if (s != 0)
return s < 0;
else if (a.MM != b.MM)
return a.MM < b.MM;
else if (a.DD != b.DD)
return a.DD < b.DD;
else if (a.hh != b.hh)
return a.hh < b.hh;
else if (a.mm != b.mm)
return a.mm < b.mm;
}
如果想要字典序升序输出,就应像如图所示,而不能像像下面这样
bool cmp(Deal a, Deal b)
{
if (a.name!=b.name)
return a.name < b.name;
else if (a.MM != b.MM)
return a.MM < b.MM;
else if (a.DD != b.DD)
return a.DD < b.DD;
else if (a.hh != b.hh)
return a.hh < b.hh;
else if (a.mm != b.mm)
return a.mm < b.mm;
}
这会报错。要使用strcmp来比较是否相等,然后用其返回值与0比较来看是升序还是降序。
主函数先是输入数据,然后是排序,这都不难,关键是计算话费:
for (i = 0; i < N-1; i++)
{
if (strcmp(deal[i].name, deal[i + 1].name) == 0)
{
if (deal[i].OnorOff == 0 && deal[i + 1].OnorOff == 1)
{
exist = 1;
int premin = deal[i].DD * 1440 + deal[i].hh * 60 + deal[i].mm;
int aftmin = deal[i + 1].DD * 1440 + deal[i + 1].hh * 60 + deal[i + 1].mm;
int totalmin = aftmin - premin;
int cost = 0;
int startmm = deal[i].mm;
int starthh = deal[i].hh;
while (startmm != totalmin+ deal[i].mm)
{
startmm++;
cost += perhour[starthh];
if (startmm % 60 == 0)
starthh++;
if (starthh > 23)
starthh = 0;
}
if (cost != 0)
{
if (name == 0)
{
printf("%s %02d\n", deal[i + 1].name, deal[i + 1].MM);
name = 1;
}
printf("%02d:%02d:%02d %02d:%02d:%02d", deal[i].DD, deal[i].hh, deal[i].mm, deal[i + 1].DD, deal[i + 1].hh, deal[i + 1].mm);
printf(" %d $%d.%02d\n", totalmin, cost / 100, cost % 100);//注意02d
totalcost += cost;
}
}
}
else
{
name = 0;
if(totalcost !=0)
printf("Total amount: $%d.%02d\n", totalcost / 100, totalcost % 100);
totalcost = 0;
exist = 0;
}
}
if (totalcost != 0)
printf("Total amount: $%d.%02d\n", totalcost / 100, totalcost % 100);
注意,有效通话在排序之后应满足如下条件,即前后两条记录名称相同,一条是通话一条是挂断,这样才能够计算话费。计算之后如果话费非0,输出名字和话费。利用旗语name来输出且只输出一次名字和月份,利用exist来保证有可用的通话记录。
三、总结
其他地方都对,但是只有测试点一过了,话费的%02d花了我一个多小时才找出来,然后加了十分。真是心酸啊。
PS:代码如下:
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Deal
{
char name[21];
int MM;
int DD;
int hh;
int mm;
int OnorOff;
}deal[1000];
int perhour[24] = { 0 };
bool cmp(Deal a, Deal b)
{
int s = strcmp(a.name, b.name);
if (s != 0)
return s < 0;
else if (a.MM != b.MM)
return a.MM < b.MM;
else if (a.DD != b.DD)
return a.DD < b.DD;
else if (a.hh != b.hh)
return a.hh < b.hh;
else if (a.mm != b.mm)
return a.mm < b.mm;
}
int main()
{
int i;
for (i = 0; i < 24; i++)
scanf("%d", &perhour[i]);
int N;
scanf("%d", &N);
for (i = 0; i < N; i++)
{
scanf("%s %d:%d:%d:%d", &deal[i].name, &deal[i].MM, &deal[i].DD, &deal[i].hh, &deal[i].mm);
string onlineoroffline;
cin >> onlineoroffline;
if (onlineoroffline.compare("on-line")==0)
deal[i].OnorOff = 0;
else
deal[i].OnorOff = 1;
}
sort(deal, deal + N, cmp);
int name = 0;
int totalcost = 0;
int exist = 0;
for (i = 0; i < N-1; i++)
{
if (strcmp(deal[i].name, deal[i + 1].name) == 0)
{
if (deal[i].OnorOff == 0 && deal[i + 1].OnorOff == 1)
{
exist = 1;
int premin = deal[i].DD * 1440 + deal[i].hh * 60 + deal[i].mm;
int aftmin = deal[i + 1].DD * 1440 + deal[i + 1].hh * 60 + deal[i + 1].mm;
int totalmin = aftmin - premin;
int cost = 0;
int startmm = deal[i].mm;
int starthh = deal[i].hh;
while (startmm != totalmin+ deal[i].mm)
{
startmm++;
cost += perhour[starthh];
if (startmm % 60 == 0)
starthh++;
if (starthh > 23)
starthh = 0;
}
if (cost != 0)
{
if (name == 0)
{
printf("%s %02d\n", deal[i + 1].name, deal[i + 1].MM);
name = 1;
}
printf("%02d:%02d:%02d %02d:%02d:%02d", deal[i].DD, deal[i].hh, deal[i].mm, deal[i + 1].DD, deal[i + 1].hh, deal[i + 1].mm);
printf(" %d $%d.%02d\n", totalmin, cost / 100, cost % 100);
totalcost += cost;
}
}
}
else
{
name = 0;
if(totalcost !=0)
printf("Total amount: $%d.%02d\n", totalcost / 100, totalcost % 100);
totalcost = 0;
exist = 0;
}
}
if (totalcost != 0)
printf("Total amount: $%d.%02d\n", totalcost / 100, totalcost % 100);
}