2021年浙大软院推免机试题解和复试准备建议

今年参加了浙江大学软件学院的推免复试,分为机试和面试,复试成绩=机试成绩×15%+面试成绩×85%。虽然机试占比不大,但是相对来说在取消PAT考试成绩抵机试后,机试的难度相比PAT甲级考试略大,同学之间的差距也会比较大,且机试成绩会影响面试老师的高低。据去年和今年的录取结果来看,机试90+基本是稳录取,80+也是大概率录取,所以如果想去浙大软院读研,机试非常重要。

本次浙软的机试我考了96分(第二题21分,其他三题AC),在600考生中排名20多,最后总分是前二十。下面主要说一说机试的代码,以及我准备浙软机试、面试的经历和感想,也希望可以帮助到想要来浙软的学弟学妹。(附上浙软的复试通知)

在这里插入图片描述

机试题解

第一题

第一题是一个求解数字的问题,不太记得题目了,难度比较小,AC代码如下。

#include using namespace std;unordered_map<int, int> ump;bool prime(int p) {for (int j = 2; j * j <= p; j++) {if (p % j == 0)return false;}return true;
}int product(int p) {int res = 1;while (p > 0) {res *= p % 10;p /= 10;}return res;
}bool yanzheng(int a, int b, int t) {string sa = to_string(a), sb = to_string(b);reverse(sa.begin(), sa.end());reverse(sb.begin(), sb.end());if (abs(b - stoi(sa)) <= t)return true;if (abs(a - stoi(sb)) <= t)return true;return false;
}int main() {int n1, n2, t, cnt = 1;scanf("%d %d %d", &n1, &n2, &t);unordered_map<int, int> ump;vector<int> res;for (int i = 2; i < 1000000; i++) {if (prime(i))ump[i] = cnt++;}for (int i = n1; i <= n2; i++) {if (ump[i] != 0) {string s = to_string(i);reverse(s.begin(), s.end());int rev = stoi(s);if (ump[rev] != 0) {int flag1 = 0, flag2 = 0;if (yanzheng(ump[i], ump[rev], t))flag1 = 1;if (abs(ump[i] - product(i)) <= t)flag2 = 1;if (flag1 == 1 && flag2 == 1)res.push_back(i);}}}for (int i = 0; i < res.size(); i++) {printf("%d\n", res[i]);}return 0;
}

第二题

第二题是一段话的字符串匹配+替换,给了一本书的一大段话以及一些语句的替换规则,要求输出替换后的话。这题我只得了21分,做了快2个小时,还是没办法AC,代码是21分,希望大佬可以指点指点哪儿错了。需要注意替换的空格和字母大小写问题。

#include using namespace std;int main() {int n, daxie = 1;string s1, s2, article, res;scanf("%d\n", &n);vector<pair<string, string>> translate;for (int i = 0; i < n; i++) {getline(cin, s1);getline(cin, s2);for (int j = 0; j < s1.length(); j++) {if (s1[j] >= 'A' && s1[j] <= 'Z') {s1[j] = s1[j] + 'a' - 'A';}}translate.emplace_back(s1, s2);}getline(cin, article);for (int i = 0; i < article.length(); i++) {int flag = 1;for (int j = 0; j < translate.size(); j++) {if (article[i] == translate[j].first[0] || article[i] + 'a' - 'A' == translate[j].first[0]) {string temp = article.substr(i, translate[j].first.length());for (int k = 0; k < temp.length(); k++) {if (temp[k] >= 'A' && temp[k] <= 'Z') {temp[k] = temp[k] + 'a' - 'A';}}if (temp == translate[j].first) {string t = translate[j].second;if ((article[i] >= 'A' && article[i] <= 'Z') && (t[0] >= 'a' && t[0] <= 'z')) {t[0] = t[0] - 'a' + 'A';} else if ((article[i] >= 'a' && article[i] <= 'z') && (t[0] >= 'A' && t[0] <= 'Z')) {t[0] = t[0] + 'a' - 'A';}i += translate[j].first.length() - 1;res += t;flag = 0;break;}}}if (flag == 1)res += article[i];}for (int i = 0; i < res.length(); i++) {if (res[i] == 'i') {if (res[i - 1] == ' ') {if (i != res.length() - 1 && res[i + 1] == ' ')printf("I");else printf("i");} else printf("%c", res[i]);} else printf("%c", res[i]);}return 0;
}

第三题

这题是一个模拟题,难度较小。题意是给定一些人的关注关系,网红是被关注的人数大于一个值,且因为网红高傲,不会关注关注他们的用户,求解所有的网红。可以直接使用vector求解,AC代码如下。

#include using namespace std;int main() {int n, m, t, a, b;scanf("%d %d %d", &n, &m, &t);vector<unordered_map<int, int>> celebrity(n + 1);vector<int> iscelebrity(n + 1, 1), count(n + 1, 0);vector<int> res;for (int i = 0; i < m; i++) {scanf("%d %d", &a, &b);if (celebrity[b][a] == 1) {iscelebrity[b] = 0;iscelebrity[a] = 0;//如果b被a关注了,且这里b关注了a,则b不是网红,a也不是网红}celebrity[a][b] = 1;//a被b关注count[a]++;//a被关注的数量+1}for (int i = 1; i <= n; i++) {if (iscelebrity[i] == 1 && count[i] >= t)res.push_back(i);}if (res.empty())printf("None");else {for (int i = 0; i < res.size(); i++) {if (i != 0)printf(" ");printf("%d", res[i]);}}return 0;
}

第四题

第四题是个板子题,求解AVL数的翻转,以及求两节点的关系。翻转方面完全是板子题,在PAT甲级模拟题后面有一样的题目,而求解两个节点的关系可以先遍历一遍树,存储其子节点和兄弟节点,这样的话比较方便。

#include using namespace std;struct TreeNode {int val;TreeNode *left, *right;TreeNode(int val) : val(val), left(nullptr), right(nullptr) {}
};TreeNode *leftRotate(TreeNode *root) {TreeNode *temp = root->right;root->right = temp->left;temp->left = root;return temp;
}TreeNode *rightRotate(TreeNode *root) {TreeNode *temp = root->left;root->left = temp->right;temp->right = root;return temp;
}TreeNode *leftRightRotate(TreeNode *root) {root->left = leftRotate(root->left);return rightRotate(root);
}TreeNode *rightLeftRotate(TreeNode *root) {root->right = rightRotate(root->right);return leftRotate(root);
}int getHeight(TreeNode *root) {if (root == nullptr)return 0;int l = getHeight(root->left);int r = getHeight(root->right);return max(l, r) + 1;
}TreeNode *buildMyTree(TreeNode *root, int val) {if (root == nullptr)root = new TreeNode(val);else if (root->val > val)root->left = buildMyTree(root->left, val);else root->right = buildMyTree(root->right, val);int l = getHeight(root->left), r = getHeight(root->right);if (l - r > 1) {if (val < root->left->val) {root = rightRotate(root);} else root = leftRightRotate(root);} else if (r - l > 1) {if (val > root->right->val) {root = leftRotate(root);} else root = rightLeftRotate(root);}return root;
}int main() {int n, m, t, a, b;string s;scanf("%d", &n);TreeNode *root = nullptr;for (int i = 0; i < n; i++) {scanf("%d", &t);root = buildMyTree(root, t);}unordered_map<int, pair<int, int>> child;unordered_map<int, int> siblings;queue<TreeNode *> q;if (root != nullptr)q.push(root);while (!q.empty()) {int currentSize = q.size();for (int i = 0; i < currentSize; i++) {auto node = q.front();int right = -1, left = -1;q.pop();if (node->left != nullptr) {q.push(node->left);left = node->left->val;}if (node->right != nullptr) {q.push(node->right);right = node->right->val;}child[node->val] = {left, right};if (left != -1 && right != -1) {siblings[left] = right;siblings[right] = left;}}}scanf("%d\n", &m);while (m > 0) {m--;int flag = 0;scanf("%d", &a);cin >> s;if (s == "is") {cin >> s;cin >> s;if (s == "root") {if (a == root->val) {flag = 1;}} else if (s == "parent") {cin >> s;scanf("%d", &b);if (child[a].first == b || child[a].second == b)flag = 1;} else if (s == "left") {cin >> s;cin >> s;scanf("%d", &b);if (child[b].first == a)flag = 1;} else if (s == "right") {cin >> s;cin >> s;scanf("%d", &b);if (child[b].second == a)flag = 1;}} else if (s == "and") {scanf("%d", &b);if (siblings[a] == b)flag = 1;}getline(cin, s);if (flag == 1)printf("Yes\n");else printf("No\n");}return 0;
}

面试过程

浙大软院的面试是一个人20分钟,其中个人PPT介绍5-8分钟,包括1分钟的英文介绍。据我了解,每个组的问问题差别很大,但是主要是项目、408专业课、数学(线代和概率论)以及语言基础(c、c++、java)。

我个人的面试题目如下:

  • 介绍线性代数的矩阵秩是什么意思?

  • 介绍一下正定矩阵的定义?

  • 多个点拟合使用什么算法?

  • 面向对象和面向过程的区别,面向对象的性质?

  • C++和java的面向对象多态性区别

  • C语言的局部变量(栈)和全局变量存储位置(堆)

  • 软件项目管理的流程,用的什么教材,一个理论(听不清楚)

  • 介绍一下软件测试黑盒、白盒,如何评价白盒测试的好坏?

  • 介绍一下论文中提到的算法?

对我来说,浙软的面试过程十分煎熬,之前听学长说浙软侧重项目,以及计网、数据结构、操作系统这些,在面试前我也把都复习了一遍。然而面试上来就是数学三连问( 线代大一学的,基本没复习),以及编程语言基础知识。因为没有认真复习这些,回答的模模糊糊。

在结束以后问了几个参加面试的同学,有的人一个专业课都没有,全部是问项目。总结可能是因为我的项目老师们不太懂,没办法问。所以有和老师相关的项目也是非常重要滴。不过最后的面试分数还可以,可能因为我的机试和个人条件还行。

准备建议

浙大软院从今年开始不能使用当年的PAT甲级和顶级成绩抵消机试,这两年的机试难度和PAT类似,可能略高一点。我个人是刷PAT的甲级真题,也就是官网的150多题,如果把这些题独立做完,机试90+一般没有问题。也可以关注关注大佬的题解,学习其思路,这里推荐柳神,我也是学习了不少她的题解。

面试其实就没什么好说的了,专业课+项目,需要认真复习。其中个人背景(rank、奖项)也是面试打分依据之一。另外需要注意,浙大软院面试需要交一页个人简历,**千万不要把自己不熟悉的课程写上去!!!**后来我才发现我交上去的个人简历有线代、C等成绩(因为成绩比较高),这也是需要避坑的。

对于双非本科的同学,或者是rk比较低的同学,可以考虑参加夏令营。浙软夏令营是个海王营,放1000+人进来,但是放弃的人也非常多。只要坚持做完项目得到优营的概率就挺大,今年的预推免初审也是刷掉了很多很多优秀的同学,听说有双非rk1acm金大佬。

写在最后

浙软这几年的政策变化很大,听说新院长张来后有不少操作,所以一定要注意最新的政策。今年的浙软口碑相比往年差了一点,但是热度却丝毫不减。我觉得浙软对于cs的学生来说,仁者见仁智者见智,适合自己的就是比较好的~

个人博客:randyzhang的个人博客
知乎:柠檬到了的知乎


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部