Problem A: 超大型 LED 显示屏
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
#include<stdio.h>
#include<string.h>
int ti[1000];
int find(int a)//多少灯管
{
if(a==0)
return 6;
if(a==1)
return 2;
if(a==2)
return 5;
if(a==3)
return 5;
if(a==4)
return 4;
if(a==5)
return 5;
if(a==6)
return 6;
if(a==7)
return 3;
if(a==8)
return 7;
if(a==9)
return 6;
}
int get(int a)
{
int sum=0;
if(a==0)
return 6;
while(a)
{
sum+=find(a%10);
a/=10;
}
return sum;
}
int main()
{
int cas=1;
char ss[100],s[100];
int sta_time,end_time;
int time,pre,sc;
int a,b,c,f[10];
while(scanf("%s %d:%d:%d",ss,&a,&b,&c)!=EOF)
{
memset(f,0,sizeof f);
sta_time=a*3600+b*60+c;
pre=sta_time;
int ans=0;
while(1)
{
scanf("%s %d:%d:%d",ss,&a,&b,&c);
if(strcmp(ss,"END")==0)
{
end_time=a*3600+b*60+c;
break;
}
scanf("%s %d",s,&sc);
time=a*3600+b*60+c;
ans+=(get(f[1])+get(f[0]))*(time-pre);
pre=time;
if(strcmp(s,"home")==0)
f[0]+=sc;
else
f[1]+=sc;
}
ans+=(get(f[1])+get(f[0]))*(end_time-pre);
printf("Case %d: ",cas++);
printf("%d\n",ans);
}
return 0;
}
Problem B: 残缺的棋盘
Description
在国际象棋里,王是最重要的一个棋子。每一步,王可以往上下左右或者对角线方向移动一
步,如下图所示。
给定两个格子 A(r1,c1), B(r2,c2),你的任务是计算出一个王从 A 到 B 至少需要走多少步。为了
避免题目太简单,我们从棋盘里拿掉了一个格子 C(r3,c3)(ABC 保证互不相同),要求王从 A
走到 B 的过程中不能进入格子 C。在本题中,各行从上到下编号为 1~8,各列从左到右编号为
1~8。
Input
输入包含不超过 10000 组数据。每组数据包含 6 个整数 r1, c1, r2, c2, r3, c3 (1<=r1, c1, r2, c2, r3,
c3<=8). 三个格子 A, B, C 保证各不相同。
Output
对于每组数据,输出测试点编号和最少步数
Sample Input
1 1 8 7 5 6
1 1 3 3 2 2
Sample Output
Case 1: 7
Case 2: 3
思路
确认对角线上是否存在残缺,如若存在+1。
#include<stdio.h>
#include<stdio.h>
int main()
{
int r1,c1,r2,c2,r3,c3;
int z=1;
while(scanf("%d%d%d%d%d%d",&r1,&c1,&r2,&c2,&r3,&c3)!=EOF)
{
int n;
n=abs(r1-r2);
int m;
m=abs(c1-c2);
int sum;
if(m>n)
sum=m;
else
sum=n;
int x1 = r3 - r1, x2 = r2 - r1, y1 = c3 - c1, y2 = c2 - c1;
if (x1*y2 - x2 * y1 == 0)//若两向量在同一直线上(终点都为r1,c1所以平行时可以理解为两向量在同一直线上)
{
if (abs(x2) == abs(y2))//等腰三角形时
if (x1*x1 + y1 * y1<x2*x2 + y2 * y2)//向量AB比向量AC长(即C落在线段AB内)
if (x1*x2 >= 0 && y1*y2 >= 0)//向量同向
sum += 1;//此时要多走一步(方法是向旁边的点先走一步,然后对角线走过去)
}
printf("Case %d: %d\n",z++,sum);
}
return 0;
}
Problem H: wjw的火车站
Description
wjw最近新开了一座火车站...没错就是火车站,因为寒假过完同学们都该返校了,所以他准备大干一场,但是这里有一个问题,因为wjw的资金不足,所以这座火车站只有一条铁路,所有的火车从一侧进入,从另一侧出来,但是为了方便调度火车,所以wjw机智的修改了一下铁路。如下图,如果火车A首先进入铁路,然后火车B在火车A离开之前进入铁路,则火车A只有在火车B离开后才能离开。那么现在问题来了,有一串火车按给定顺序进入车站,wjw希望在通过他的一波操作使这列火车以另一个顺序开出火车站,但是他的智商并不支持他解决这个问题,所以你的任务是确定在给定进站顺序和出站顺序的情况下,给出调度操作。
Input
输入包含多组数据。每个测试数据包含一个正整数n表示火车数,接下去的两个序列表示进站顺序和出站顺序,火车编号为小写或大写字母,(a≠A)
Output
输出数据包含一个字符串“Yes.”或“No.”,表示是否有可行的调度方案,若有,则输出调度操作。
Sample Input
3 ABC CBA 3 abc cab
Sample Output
Case #1: Yes. in in in out out out Case #2: No.
栈的简单应用
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[10005];
char s2[10005];
int n;
int k=1;
while (~scanf("%d%s%s",&n,s1,s2))
{
string st[10005];
int l2=strlen(s2);
int len=0;
int l=0;
stack <char> a;
for (int i=0;i<strlen(s1);i++){
a.push(s1[i]);
st[l++]="in";
while ((!a.empty()) && s2[len]!='\0'&&a.top()==s2[len]){
len++;
a.pop();
st[l++]="out";
}
}
printf("Case #%d: ",k++);
if (len>=l2){
printf("Yes.\n");
for (int i=0;i<l;i++) cout<<st[i]<<endl;
}
else printf("No.\n");
}
}