杭电 2017 年计算机复试真题
写在前面
此题目是根据 CSDN 博客粥粥同学 发布的内容进行收集整理,记录了本人的解题过程和一些想法。仅供大家参考,如有错误,欢迎大家指出!
第一题
Problem Description
关羽过关斩三将,输入四个人的武力值(大于 0 小于 50),若超过界限需要重新输入,关羽的武力值 x,将士武力值为 y,满足(x-y)^2+(x-y)+41 若为素数则关羽获胜,若关羽三次获胜输出 WIN,若失败则输出失败的将领序号(第几关)
Input
输入首先是正整数 x,代表关羽的武力值,而后是三行 y 分别代表三个将士的武力值
Output
若关羽三次获胜输出 WIN,若失败则输出失败的将领序号(第几关)
Sample Input
Sample Output
解题思路
参考源码
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
解题思路
把模板放到材料上一一比对,若完全相同,则标记材料该模板已切出
参考源码
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; }
相关内容