ZCMU 1635: 超大型 LED 显示屏
Time Limit: 1 Sec Memory Limit: 128 MB
Description
你是学生会体育部长,负责组织一年一度的校篮球比赛。马上就要决赛了,你希望吸引更多的
人来看比赛,因此打算更新一下设备,用一个超大的 LED 屏幕来显示比分。当然,电也不是
不要钱的,所以你决定先分析一下往年的比赛,估计一下大概要耗多少电。
如上图,每个数字由 7 条线段组成,每条亮着的线段每秒钟耗电量为 1 个单位。线段不亮的时
候不耗电。为了省电,比分不显示前导 0(不过 0 分的时候要显示数字 0)。
你的 LED 显示屏共包含 6 个数字,即双方的比分各有 3 位数。
Input
输入包含不超过 100 组数据。每组数据第一行为"START hh:mm:ss",表示比赛开始时刻为
hh:mm:ss。最后一行为"END hh:mm:ss",即比赛结束时刻。二者之间至少会有一个 SCORE 信
息,格式为"SCORE hh:mm:ss team score",其中 team 要么是"home"(主场)要么是"guest"(客
场), score 表示得分,为 1,2 或者 3。这些信息保证按照时间从早到晚的顺序排列,且任意两
条 SCORE 信息的时刻均不相同。比赛开始时间不会早于 9:00,结束时间不会晚于同一天的
21:00。注意,如果比赛开始时间为 09:00:00,结束时间为 09:00:01,比赛长度为 1 秒钟,而不
是 2 秒钟。
Output
对于每组数据,输出测试点编号和总耗电量。
Sample Input
START 09:00:00
SCORE 09:01:05 home 2
SCORE 09:10:07 guest 3
END 09:15:00
START 09:00:00
SCORE 10:00:00 home 1
SCORE 11:00:00 home 1
SCORE 12:00:00 home 1
SCORE 13:00:00 home 1
SCORE 14:00:00 home 1
SCORE 15:00:00 home 1
SCORE 16:00:00 home 1
SCORE 17:00:00 home 1
SCORE 18:00:00 home 1
SCORE 19:00:00 home 1
SCORE 20:00:00 home 1
END 21:00:00
Sample Output
Case 1: 9672
Case 2: 478800
思路
这题是一个模拟题,什么都别想,他让你做什么你就做什么就好。既然思路这么简单,那么这道题解的意义在哪里呢?
意义就在于从这道题里能了解到自己敲代码时由于粗心错误手法生疏能出多少BUG.......눈_눈
模拟题要求编码严谨思路清晰,本题中每队共有三块屏幕显示分数,要求不输出前导0(也就是一个队是10分时不显示010而是显示_10,第三块屏幕熄灭),但是0分必须输出一个0,此处在判断是否为前导0时仅判断了0所在的位数,忽略了三位数不为0时二位数的0因当显示这种情况,导致WA,另外在调试途中还一度写反计算消耗电量和更新分数的顺序,导致每次计算的是更新后的分数在更新前一段时间消耗的电量......(拍死自己)
除此以外还要注意每个case结束后要初始化变量的问题。
另外本题由于代码较长,功能较多(可能是蒟蒻没做过更长的题),为了便于出BUG后调试,最好将不同的功能分函数写,分别调试好每个功能函数使它们分别正常工作,最后将它们放入主函数即可得到正常运作的程序。这样不仅方便调试bug,还降低了写程序时的思维复杂度。有效防止秃头
AC代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <cstring>
#include <string>
#include <list>
#include <algorithm>
#include <set>
#include <list>
#include <stack>
//#include <map>
//#define INF 0x3f3f3f3f
//#define N 200000
using namespace std;
int consumelist[10] = { 6,2,5,5,4,5,6,3,7,6 };
char status[7];
int homescore;
int guestscore;
long long int cost;
//储存当前时间
int h, m, s;
//储存上次更新数据的时间
int ht, mt, st;
//更改分数
void update_score()
{
char team[7];
int score;
scanf("%s%d", team, &score);
//判断新的分数是哪一队得的
if (strcmp(team, "home") == 0)homescore += score;
else if (strcmp(team, "guest") == 0)guestscore += score;
}
//返回每次更新数据前的耗电量
int count_consume()
{
int consume = 0;
//分别用于标记主队和客队分数中间遍历到的0前是否有大于0的数,若有则不能当做前导0去掉,此处未判断导致WA
bool flagh = false, flagg = false;
for (int i = 2; i >= 0; i--)
{
//当判断的是十位数及以上时判断是否有需要去掉的前导0
if (i != 0)
{
int dev = pow(10, i);
if (homescore / dev % 10 != 0)
{
consume += consumelist[homescore / dev % 10];
flagh = true;
}
else if (flagh == true)
{
consume += consumelist[homescore / dev % 10];
}
if (guestscore / dev % 10 != 0)
{
consume += consumelist[guestscore / dev % 10];
flagg = true;
}
else if (flagg == true)
{
consume += consumelist[guestscore / dev % 10];
}
}
//个位数直接加上,不考虑去除前导0
else
{
consume += consumelist[homescore % 10];
consume += consumelist[guestscore % 10];
}
}
return consume;
}
//返回本次更新数据和前一次更新数据的时间间隔同时更新前次更新数据的时间
long long count_time()
{
long long time = (h - ht) * 60 * 60 + (m - mt) * 60 + (s - st);
ht = h; mt = m; st = s;
return time;
}
int main()
{
int hs, ms, ss;
long long c = 1;
while (scanf("%s%d:%d:%d", status, &hs, &ms, &ss) != EOF)
{
//记得初始化
cost = 0;
homescore = 0;
guestscore = 0;
bool flag = false;
//将开始时间计入前次更新数据的时间
ht = hs; mt = ms; st = ss;
while (!flag)
{
scanf("%s%d:%d:%d", status, &h, &m, &s);
//计算更新分数前的耗电量
int consume = count_consume();
long long int time = count_time();
cost += consume * time;
//若输入SCORE更新分数
if (strcmp(status, "SCORE") == 0)update_score();
//若输入END结束比赛
else if (strcmp(status, "END") == 0)flag = true;
if (flag)
{
printf("Case %lld: %lld\n", c++, cost);
}
}
}
return 0;
}