杭电2013年计算机复试真题

注意:此复试题目是根据CSDN博客逃离地球的小小呆上发布的回忆版整理复原。为了恢复试题的原貌,我根据试题要求进行合理的脑补,按照oj系统的风格补全了试题的Problem Description、Input、Output、Sample Input、Sample Out等内容,并加入了详解、具体的代码实现。因为是复原版,不能保证当时的题目就是这么呈现的,也不能说明考场上的试题就是oj风格叙述的,仅供大家参考。有什么错误、不合理的地方欢迎指出。
原创不易,还请大家多支持

第一题

Problem Description

输入两个时间(格式HH:MM:SS),你需要用前面时间减去后面时间,输出两个时间的差值(若前面的时间比后面的时间小,则把前面的时间当做是第二天来处理)

Input

有多组测试数据,每组数据中有一个数字n表示共有多少组时间需要计算。接下来有n行,每一行包含两个时间HH:MM:SS,中间用空格隔开

Output

输出所给两时间的时间差,格式HH:MM:SS,不够两位的数字前面要补0。对于每组时间输出一行

Sample Input

3
15:08:32 16:07:32
10:32:26 8:53:26
23:05:59 20:15:00

Sample Output

23:01:00
01:39:00
02:50:59
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<stdio.h>

int main() {
int n;
while (scanf("%d", &n) != EOF)
{
for (int i = 0; i < n; i++)
{
int h1, m1, s1;
int h2, m2, s2;
scanf("%d:%d:%d", &h1, &m1, &s1);//输入两个时间
scanf("%d:%d:%d", &h2, &m2, &s2);
int hd = h1 - h2;//先计算两时间的小时差值
int md = m1 - m2;//分钟差值
int sd = s1 - s2;//秒差值
if (sd<0)//若后面时间的秒比前面的大
{
sd += 60;
md -= 1;
}
if (md<0)//若后面时间的分比前面的大
{
md += 60;
hd -= 1;
}
if (hd<0)//若后面时间的小时比前面的大
hd += 24;
printf("%02d:%02d:%02d\n", hd, md, sd);//控制输出格式
}
}
return 0;
}

这道题也很简单,基本上就是考察逻辑思维能力、基本代码能力。由于题目固定要求前一个时间减去都一个时间,注意前面时间比后面时间小的情况即可。同时注意输出格式的控制

第二题

Problem Description

一个活动有N个人参加,一个主持人和N-1个普通参加者,其中所有的人都认识主持人,主持人也认识所有的人,主持人要求N-1个参加者说出他们在参加者中所认识的人数,如果A认识B,则B认识A。那么,所有人都最少会认识一个人,那个人就是主持人。现在,他们说出了自己所认识的人数,你需要判断他们中有没有人说谎。

Input

有多组测试数据,每组数据中有一个数字n表示共有多少人参加这个活动。接下来有n-1个整数,表示除主持人外n-1个普通参加者认识的人数,中间用空格隔开。当n=0时表示结束

Output

若他们之中有人撒谎,输出一行"Lie absolutely",否则输出一行"Maybe truth"

Sample Input

7
1 2 4 5 5 3
9
3 7 7 7 7 5 6 6

Sample Output

Lie absolutely
Maybe truth

这道题相当有意思,也应该是截至到2013年最有难度的。

首先,我们可以把这个场景看成是一个图,每个人都是一个点,最开始每个点都和中心点(主持人)有连线。接下来,每个人都开始说,自己有几根连线(也就是自己认识多少人),我们把所有人(除主持人)的连线都切除,那么如果没有人撒谎的话,最后应该每个人都只有一条连接主持人的线。同时,我们并不知道谁连着谁,所以我们在切线的时候,优先斩断线多的点。

我们先对关系数组(保存每个人认识多少人的数组)进行排序,找出那个认识人最多的人。将他的关系除主持人外全部斩断,如果这个人认识x个人,那我们就把排在其后的x-1个人的关系数都减1,然后将这个人关系数置为1。然后再排序,相减,依次循环,遍历数组中所有元素都执行此步骤。这样就把所有人(除主持人)的连线都切除了。此时若存在有人的关系数为0,那就一定证明有人撒谎。

就拿第一个输入作为栗子:

7
1 2 4 5 5 3

  • 5 5 4 3 2 1 先进行排序
  • 1 4 3 2 1 1 斩断第一个人除主持人外的所有关系,并将其关系数置为1
  • 1 4 3 2 1 1 除开第一个人,再进行排序
  • 1 1 2 1 0 1 斩断第二个人除主持人外的所有关系,并将其关系数置为1
  • 1 1 2 1 1 0 除开第二个人,再进行排序。但最后一个人的关系居然是0,那么肯定有人撒谎!

以上就大概说明了判断的思路,若在这个过程结束之后所有人的关系数都是1,那么这种情况就是可能的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <algorithm>
using namespace std;
bool cmp(int a, int b) {//定义比较方法,使sort函数倒序排列数组
return a > b;
}
int main() {
int n;
while (scanf("%d",&n)!=EOF)
{
if (n == 0)//n=0结束
break;
int r[101];//保存关系的数组
for (int i = 0; i < n-1; i++)
scanf("%d", &r[i]);
for (int i = 0; i < n-1; i++)
{
sort(r + i, r + n - 1, cmp);//先对关系数组从大到小排序
if (r[n - 2] == 0 || r[0] > n)//若认识人数最少的那个人关系数是0,或认识人最多的那个人关系数大于n
{
puts("Lie absolutely");
break;
}
else if (r[i] == 1)//若认识人数最多的那个人关系数是1
{
puts("Maybe truth");
break;
}
for (int j = 1; j< r[i]; j++)//若没判断出来,则斩断关系
r[i + j]--;//将其后面r[i]-1个人的关系数都减1
r[i] = 1;//将其关系数置为1
}
}
}
文章作者: Teily
文章链接: https://teily.cn/article/HDU2013.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 TeilyMa's Blog