杭电 2017 年计算机复试真题

写在前面

此题目是根据 CSDN 博客粥粥同学发布的内容进行收集整理,记录了本人的解题过程和一些想法。仅供大家参考,如有错误,欢迎大家指出!


第一题

Problem Description

关羽过关斩三将,输入四个人的武力值(大于 0 小于 50),若超过界限需要重新输入,关羽的武力值 x,将士武力值为 y,满足(x-y)^2+(x-y)+41 若为素数则关羽获胜,若关羽三次获胜输出 WIN,若失败则输出失败的将领序号(第几关)

Input

输入首先是正整数 x,代表关羽的武力值,而后是三行 y 分别代表三个将士的武力值

Output

若关羽三次获胜输出 WIN,若失败则输出失败的将领序号(第几关)

Sample Input

46
30
20
10

Sample Output

Win

解题思路

判断是否为素数即可

参考源码

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
#include <cmath>
#include <iostream>
using namespace std;
bool isprime(int a) {
if (a <= 1) return false;
for (int i = 2; i <= sqrt(a); i++)
if (a % i == 0) return false;
return true;
}
void input(int &x) { //输入模块
cin >> x;
while (x <= 0 || x >= 50) {
cout << "input again" << endl;
cin >> x;
}
}
int main() {
int x, y, c = 0;
input(x);
while (c < 3) {
input(y);
c++;
if (!isprime((x - y) * (x - y) + (x - y) + 41)) {
cout << "Fail 第" << c << "关" << endl;
return 1;
}
}
cout << "Win" << endl;
return 0;
}

第二题

Problem Description

输入 N 个员工,每个员工输出 ID 号,上班时间,下班时间,
第一行输出最早去的员工的 ID 和上班时间
第二行输出最迟走的员工的 ID 和下班时间
第三行输出工作最久的员工的 ID 和上班时间

Input

第一行包含一个正整数 n,表示输入的员工数,接下来有 n 行,每一行包括员工 ID、上班时间、下班时间

Output

第一行输出最早去的员工的 ID 和上班时间
第二行输出最迟走的员工的 ID 和下班时间
第三行输出工作最久的员工的 ID 和上班时间

Sample Input

3
100001 07:00:00 17:00:00
100002 08:00:00 18:00:00
100003 09:00:00 21:00:00

Sample Output

100001 07:00:00
100003 21:00:00
100003 09:00:00

解题思路

需要定义时间以及员工结构体,换算时间,再通过 sort()函数排序得到

参考源码

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
35
36
37
38
39
40
41
42
43
44
45
46
#include <algorithm>
#include <iostream>
using namespace std;
struct worker {
char id[20];
struct time {
int h, m, s;
} start, end;
int d;
} w[1000];
bool cmp1(worker a, worker b) { //第一行
if (a.start.h != b.start.h)
return a.start.h < b.start.h;
else if (a.start.m != b.start.m)
return a.start.m < b.start.m;
else
return a.start.s < b.start.s;
}
bool cmp2(worker a, worker b) { //第二行
if (a.end.h != b.end.h)
return a.end.h > b.end.h;
else if (a.end.m != b.end.m)
return a.end.m > b.end.m;
else
return a.end.s > b.end.s;
}
bool cmp3(worker a, worker b) { return a.d > b.d; } //第三行
int main() {
int n;
char ch;
while (cin >> n) {
for (int i = 0; i < n; i++) {
cin >> w[i].id >> w[i].start.h >> ch >> w[i].start.m >> ch >> w[i].start.s >>
w[i].end.h >> ch >> w[i].end.m >> ch >> w[i].end.s;
w[i].d = (w[i].end.h * 3600 + w[i].end.m * 60 + w[i].end.s) -
(w[i].start.h * 3600 + w[i].start.m * 60 + w[i].start.s); //换算为秒
}
sort(w, w + n, cmp1);
printf("%s %02d:%02d:%02d\n", w[0].id, w[0].start.h, w[0].start.m, w[0].start.s);
sort(w, w + n, cmp2);
printf("%s %02d:%02d:%02d\n", w[0].id, w[0].end.h, w[0].end.m, w[0].end.s);
sort(w, w + n, cmp3);
printf("%s %02d:%02d:%02d\n", w[0].id, w[0].start.h, w[0].start.m, w[0].start.s);
}
return 0;
}

第三题

Problem Description

有一个长 M 宽 N 的材料和一个长 s 宽 t 的模板,从材料中切除模板,求最大能切出来的模板的数量

Input

输入包含多个测试实例,第一行是 N,M,而后是N*M的矩阵,之后是 s,t,而后是s*t的矩阵,代表模板大小

Output

输出最大能切出来的模板的数量

Sample Input

3 4
a b c d
c d a b
a c c d
2 2
a b
c d

Sample Output

2

解题思路

把模板放到材料上一一比对,若完全相同,则标记材料该模板已切出

参考源码

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
35
36
37
38
39
40
41
42
43
#include <cstring>
#include <iostream>
using namespace std;
char map1[1000][1000];
char map2[1000][1000];
bool vis[1000][1000];
int main() {
int n, m, s, t;
while (cin >> n >> m) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) cin >> map1[i][j];
cin >> s >> t;
for (int i = 0; i < s; i++)
for (int j = 0; j < t; j++) cin >> map2[i][j];

memset(vis, false, sizeof(vis));
int count = 0;
for (int i = 0; i <= n - s; i++) { // i,j为小矩阵可以放置起始位置
for (int j = 0; j <= m - t; j++) {
if (!vis[i][j]) { //若未被访问
int flag = 0;
for (int p = 0; p < s; p++) { //遍历模板
for (int q = 0; q < t; q++) {
if (map1[i + p][j + q] == map2[p][q]) { //比较
flag++;
}
}
}
if (flag == s * t) { //若可以切割
count++;
for (int p = 0; p < s; p++) {
for (int q = 0; q < t; q++) {
vis[i + p][j + q] = true; //标记为已访问
}
}
}
}
}
}
cout << count << endl;
}
return 0;
}

相关内容