我参加了2020.10.11-10.12的北航推免
面试和机考都高分通过
北航机考要求c/c++编程,采用标准库,今年也破天荒的可以使用STL(但事实证明出的题目好像没什么需要STL的emmmm)
编译环境要求:
C语言程序使用 ISO C11 标准来编译程序,gcc版本为gcc(GCC)4.8.5 20150623(Red Hat4.8.5-36);
**C++**语言使用 2011 ISO C++ 作为标准来编译程序,g++版本为g++(GCC)4.8.5 20150623(Red Hat4.8.5-36)。
保险起见大家还是下载对应版本进行练习,防止考试出现大问题
由于我对c++语言并不熟悉,因为采用标准c编程
熟悉结构体、链表、指针、字符串操作
baidu搜索“北航机考”,无数往年题可以刷
当然如果你是本校的非常建议到judge.buaa.edu.cn(其实也是考试平台)刷一下高级语言程序设计(一)的题目(大概50题左右?),个人觉得帮助还是蛮大的,题型应该也挺像(因为机考题目就来自高级语言程序设计题库改编)
经过我对往年题的研究,我发现北航考题无非就是字符串操作/数组操作+数据结构的知识(尤其是树,考的频率特别高)
一般第一题60分 第二题40分
第一题会比较简单,但感觉坑也会多一点,还是好好审题吧
第二题会稍微增加难度,我感觉熟悉数据结构知识的话问题应该不大
机考是决定能否通过最重要的因素,如果你机考够高,面试几乎不可能被刷
今年大概200多人参加机考,最后只有一半的人活下来了,北航一般比较喜欢编程能力强的,因此机考真的很重要。
第一题:
输入:
一句c语言的非控制类(不包括if/while等)语句,如a=find(b+c)+d这样的
输出:
输出函数调用及传入的参数
例如:
输入:
a = function(1, 2 + 3, d) + functio() + functi( 1+ b+ d);
输出
function 1 2+3 d
functio
functi 1+b+d
几个坑需要全面考虑
(1)输入中可能含有任意空格,但输出不能有
(2)函数传入的参数可以为表达式、数字常量,变量,但不会有字符和字符串常量(题目规定)
(3)不会有括号嵌套(题目规定)
(4)函数名不含数字
其实我的思路挺简单的
(1)从头到尾扫描去空格
(2)规定分隔符
(3)if next is ‘(’, 判断前面抓到的串是否是合法函数名(例如不会有数字,但可能有_之类的)
(4)以,为分隔扫描出所有参数
代码
#include
#include
#include
//judge legal char
int isLegal(char a) {
if (a >= 'a' && a <= 'z') {
return 1;
}
if (a >= 'A' && a <= 'Z') {
return 1;
}
if (a == '_' || (a >= '0' && a <= '9')) {
return 1;
}
return 0;
}
//judge legal function begin
int isLegalBegin(char a) {
if (a >= 'a' && a <= 'z') {
return 1;
}
if (a >= 'A' && a <= 'Z') {
return 1;
}
if (a == '_') {
return 1;
}
return 0;
}
// main
int main() {
char string[110];
int string_len = 0;
gets(string);
string_len = strlen(string);
if (string_len == 0) {
return
}
//printf("%s\n", string);
int i, j;
for (i = 0; i < string_len; i++) {
if (string[i] == ' ' || string[i] == '\t') {
for (j = i; j < string_len - 1; j++) {
string[j] = string[j + 1];
}
string_len--;
i--;
}
}
string[string_len] = '\0';
//printf("%s\n", string);
char tmp[110];
int cnt = 0;
char var[100];
int var_len = 0;
for (i = 0; i <string_len; i++) {
//tmp[cnt] = '\0';
//printf("%s\n", tmp);
if (string[i] == '(' && cnt > 0) {
tmp[cnt] = '\0';
printf("%s", tmp);
cnt = 0;
var_len = 0;
i += 1;
while (string[i] != ')') {
if (string[i] == ',') {
if (var_len > 0) {
var[var_len] = '\0';
printf(" %s", var);
}
var_len = 0;
} else {
var[var_len++] = string[i];
}
i += 1;
}
if (var_len > 0) {
var[var_len] = '\0';
printf(" %s", var);
}
printf("\n");
} else if (cnt == 0 && isLegalBegin(string[i])) {
tmp[cnt++] = string[i];
} else if (isLegal(string[i]) == 0) {
cnt = 0;
} else {
tmp[cnt++] = string[i];
}
}
return 0;
}
第二题
这题稍微复杂点,但是熟悉数据结构中的树的各种操作(遍历)的话应该也好做
这是一个机场的场景
规定数字100代表根节点
数字<100代表登机口
数字>100代表分岔点
树的输入格式
10
100 0
101 100
3 100
1 101
2 101
102 100
103 102
4 102
5 102
6 103
也就是节点个数+该节点号和父节点号
这时候有摆渡车,输入m个乘客,从100出发,送乘客到登机口
每个乘客有优先级且送客过程如果刚好到达其他乘客要去的登机口所在的分岔点,则顺带下车
例如
3
thunder1 6 1
thunder2 3 2
thunder3 2 0
thunder4 4 3
也就是乘客个数+乘客名字和乘客目的地和优先级(最低的先送)
以上场景就是先送thunder3到2 ,100->101->2,经过100过程中由于thunder2要去3,顺路下车。然后送完thunder3和thunder2,开始送thunder1,100->102->103,经过102是顺带送thunder4到4登机口。
最终输出
thunder2 3
thunder3 2
thunder4 4
thunder1 6
总结一下就是:顺路+优先级策略
我感觉这个题很像北航OO课程的电梯问题,不过是简化了很多
本题我的思路也比较简单直接
(1)构造树
找到对应的父节点
增加一个孩子
(2)找路径(O(log n)时间内解决)
从登机口从下往上(避免了前序遍历的递归以及在O(log n)时间内就可以找到,也是空间换时间的重要策略)
再从上往下,并且判断是否顺路
代码
#include
#include
#include
//struct for multi tree node
struct Node {
int val;
int cnt;
struct Node* child[10];
struct Node* parent;
};
typedef struct Node* NODE;
//struct for customer
struct custom {
char name[110];
int pri;
int gate;
};
//array for all customers
struct custom array[1000];
int array_len = 0;
//a symbol of if visit
int visit[1000];
//selective sort for struct cunstom
void sort() {
int i,j;
int pos;
char temp[110];
int a, b;
for (i = 0; i < array_len; i++) {
pos = i;
for (j = i; j < array_len; j++) {
if (array[j].pri < array[pos].pri) {
pos = j;
}
}
if (pos != i) {
strcpy(temp, array[pos].name);
a = array[pos].gate;
b = array[pos].pri;
strcpy(array[pos].name, array[i].name);
array[pos].gate = array[i].gate;
array[pos].pri = array[i].pri;
strcpy(array[i].name, temp);
array[i].gate = a;
array[i].pri = b;
}
}
}
//find node according to val
NODE findNode(NODE root, int val) {
// printf("%d\n", val);
if (root == NULL || root->val == val) {
return root;
}
if (root->cnt == 0) {
return NULL;
}
NODE temp;
int i;
for (i = 0; i < root->cnt; i++) {
temp = findNode(root->child[i], val);
if (temp != NULL) {
return temp;
}
}
return NULL;
}
// record visit path
NODE path[100];
int path_len = 0;
//is similar to preorder
void findPath(NODE dst) {
NODE path1[100];
NODE temp = dst;
while (temp-> parent != NULL) {
temp = temp->parent;
path1[path_len++] = temp;
}
int i;
for (i = 0; i < path_len; i++) {
path[i] = path1[path_len - 1 - i];
}
}
//judge if visit
void stop(NODE temp) {
// printf("stop in %d\n", temp->val);
int i, j;
for (j = 0; j < array_len; j++) {
if (visit[j] == 1) {
continue;
}
for (i = 0; i < temp->cnt; i++) {
if (temp->child[i]->val < 100 && array[j].gate == temp->child[i]->val) {
printf("%s %d\n", array[j].name, array[j].gate);
visit[j] = 1;
break;
}
}
}
// printf("stop end\n");
}
int main() {
int n;
scanf("%d", &n);
NODE root = malloc(sizeof(struct Node));
int a, b;
NODE temp;
/*
root->cnt = 1;
root->child[0] = malloc(sizeof(struct Node));
root->child[0]->val = 4;
root->child[0]->cnt = 0;
temp = findNode(root, 4);*/
int i;
for (i = 0; i < n; i++) {
scanf("%d%d", &a, &b);
// printf("insert %d %d\n", a, b);
if (i == 0) {
root->val = a;
root->cnt = 0;
root->parent = NULL;
continue;
}
temp = findNode(root, b);
temp->child[temp->cnt] = malloc(sizeof(struct Node));
temp->child[temp->cnt]->val = a;
temp->child[temp->cnt]->parent = temp;
temp->child[temp->cnt]->cnt = 0;
temp->cnt += 1;
}
// printf("*%d*\n", findNode(root, 1)->val);
// printf("*%d*\n", findNode(root, 10)->val);
int m;
scanf("%d", &m);
char name[101];
int gate;
int pri;
for (i = 0; i < m; i++) {
scanf("%s%d%d", name, &gate, &pri);
strcpy(array[array_len].name, name);
array[array_len].gate = gate;
array[array_len].pri = pri;
array_len++;
}
sort();
/*printf("____\n");
for (i = 0; i < array_len; i++) {
printf("%s %d %d\n", array[i].name, array[i].gate, array[i].pri);
}*/
for (i = 0; i < array_len; i++) {
visit[i] = 0;
}
int j;
for (i = 0; i < array_len; i++) {
if (visit[i] == 0) {
// printf("1");
// printf("send %s\n", array[i].name);
temp = findNode(root, array[i].gate);
findPath(temp);
for (j = 0; j < path_len; j++) {
stop(path[j]);
}
visit[i] = 1;
path_len = 0;
}
//printf("1\n");
}
}
面试主要三个环节
**思想政治考察:**这部分不计入总分,只要思想正确就行
**英语考察:**英语自我介绍、听力、口语对话
**数学考查:**离散数学、高等代数、概率论、高等数学(数学分析)
**专业课:**五花八门,不过重点应该是计组、OS、数据结构、编译、网络
,然后也会设置各种各样的场景,让你分析和解决问题
我被问到的问题:
1、疫情期间我们国家如何体现“以人为本”的思想
2、What do you think of weChat?+一段我没太听清的关于Facebook和微信的发展历程介绍
3、如何求特征值和特征向量?有什么意义?
4、场景题:本地cache和web服务器之间如何保持数据更新且不能高频轮询