华为2018届校园招聘笔试题目以及相应代码分享 软件开发岗位

华为2018届校园招聘笔试

时间20170712


笔试题目

01 括号匹配

//01 括号匹配
#define _CRT_SECURE_NO_WARNINGS
/*
括号匹配

给定一个字符串,里边可能包含“()”、“[]”、“{}”三种括号,请编写程序检查该字符串中的括号是否成对出现,且嵌套关系正确。
输出:true:若括号成对出现且嵌套关系正确,或该字符串中无括号字符;
false:若未正确使用括号字符。
实现时,无需考虑非法输入。

输入描述:
输入为:
字符串

例子:(1+2)/(0.5+1)

输出描述:
输出为:
字符串

例子:true
*/

//这是josan的AC代码,仅供参考。
//程序有什么bug,有什么可以改进的地方,欢迎私信交流或者留言回复。
//共同学习,共同进步。

#include <iostream>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

bool isLeft(char a)
{
	return (a == '(') || (a == '[') || (a == '{');
}

bool isRight(char a)
{
	return (a == ')') || (a == ']') || (a == '}');
}

bool isMatch(char a, char b)
{
	if(a == '('&&b == ')')
	{
		return true;
	}
	else if(a == '['&&b == ']')
	{
		return true;
	}
	else if(a == '{'&&b == '}')
	{
		return true;
	}
	return false;
}

int main()
{
#if 0
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif
	string str;
	vector<char> cvec;
	cvec.reserve(200);
	while(cin >> str)
	{
		auto iter = str.begin();
		for(; iter != str.end(); ++iter)
		{
			//左括号直接进栈
			if(isLeft(*iter))
			{
				cvec.push_back(*iter);
			}
			//如果出现右括号
			else if(isRight(*iter))
			{
				//不合理情况1: 栈空的话,直接退出    这里情况一开始忘记考虑,但是华为机试仍然100%通过
				if(cvec.empty())
				{
					break;
				}
				char c = cvec.back();
				cvec.pop_back();
				//不合理情况2:判断栈中左括号与现在的右括号是否匹配
				if(!isMatch(c, *iter))
				{
					break;
				}
			}
		}
		//处理不合理情况1,2  以及不合理情况3:字符已经遍历结束,但是栈仍然非空
		if(iter != str.end()||!cvec.empty())
		{
			cout << "false" << endl;
		}
		else
		{
			cout << "true" << endl;
		}
	}
	return 0;
}


02 打印队列

//02 打印机任务
#define _CRT_SECURE_NO_WARNINGS
/*
打印机任务

简要描述:
某个打印机根据打印机队列执行打印任务,打印任务分为九个优先级,分别用数字1~9表示,数字越大优先级越高。打印机每次从队列头部取出第一个任务A,然后检查队列余下任务中有没有比A优先级更高的任务,则将任务A放在队列尾部,否则就执行任务A的打印。请编写一个程序,根据输入的打印队列,编出实际的打印顺序。

输入描述:
函数原型: void printOrder(const int input[], int len, int output[])
输入参数input表示打印队列,为一个由整数1~9(优先级)组成的数组,数组索引0表示打印队列头部。对于C/C++,参数len表示input数组的长度。可以假定输入的参数总是合法有效的,input数组长度有可能为0,但不会是空指针。
输出为一个表示实际打印顺序的数组,其数组项为打印任务在输入数组中的索引值(从0开始)。Java通过返回值输出。C/C++通过输出参数output[]输出,可以假定为存放结果分配了足够的空间

。。。。题目其余部分没有记录,有人记录的,可以希望在留言处补全,大家一起分享交流。

输入样例:
9, 3, 5
输出样例:
0, 2, 1
*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

#define MAX 500

int input[MAX];

//循环队列的结点数据元素
struct QNode
{
	int num;
	int idx;
};

typedef struct Que
{
	QNode* elem;
	int front;
	int rear;
	int len;
	int sz;
}CyQueue;

void initQueue(CyQueue& Q)
{
	Q.front = Q.rear = 0;
	Q.len = Q.sz = 0;
	Q.elem = nullptr;
}

bool isEmpty(CyQueue Q)
{
	return Q.len == 0;
}

int nextIdx(CyQueue Q, int cur)
{
	return (cur + 1) % (Q.sz + 1);
}

//Q 非空
//返回循环队列的最大优先级的索引号
int getMax(CyQueue Q)
{
	int maxNum = Q.front;
	int i = nextIdx(Q, Q.front);
	for(; i != Q.rear; i = nextIdx(Q, i))
	{
		if(Q.elem[i].num > Q.elem[maxNum].num)
		{
			maxNum = i;
		}
	}
	return maxNum;
}

//删除节点
void Pop(CyQueue& Q)
{
	Q.front = nextIdx(Q, Q.front);
	--Q.len;
}

//获得队头元素
QNode getFront(CyQueue& Q)
{
	return Q.elem[Q.front];
}

//插入节点
void Push(CyQueue& Q, QNode& q)
{
	Q.elem[Q.rear] = q;
	Q.rear = nextIdx(Q, Q.rear);
	++Q.len;
}

//主函数  打印序列
void printOrder(const int input[], int len, int output[])
{
	CyQueue Q;
	initQueue(Q);
	Q.len = len;
	Q.sz = len + 1;
	Q.elem = new QNode[len + 1];
	for(int i = 0; i < len; ++i)
	{
		Q.elem[i].num = input[i];
		Q.elem[i].idx = i;
	}
	Q.front = 0;
	Q.rear = len;
	int numOut = 0;
	while(!isEmpty(Q))
	{
		int pos = getMax(Q);
		for(int i = Q.front; i != pos; i = nextIdx(Q, i))
		{
			QNode q = getFront(Q);
			Pop(Q);
			Push(Q, q);
		}
		QNode q = getFront(Q);
		output[numOut++] = q.idx;
		Pop(Q);
	}
}

int main()
{
#if 1
	freopen("in01.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif
	int len = 0;
	int num;
	char c;
	while(cin >> num)
	{
		//处理逗号的输入
		cin >> c;
		input[len++] = num;
	}
	int output[MAX] = {0};
	printOrder(input, len, output);

	for(int i = 0; i < len; ++i)
	{
		if(i != len - 1)
		{
			cout << output[i] << ", ";
		}
		else
		{
			cout << output[i];
		}
	}
	return 0;
}


03 平安果

//03 平安果
#define _CRT_SECURE_NO_WARNINGS
/*
平安果

简要描述:
给定一个M行N列的矩阵(M*N个格子),每个格子中放着一定数量的平安果。
你从左上角的各自开始,只能向下或者向右走,目的地是右下角的格子。
每走过一个格子,就把格子上的平安果都收集起来。求你最多能收集到多少平安果。
注意:当经过一个格子时,需要一次性把格子里的平安果都拿走。
限制条件:1<N,M<=50;每个格子里的平安果数量是0到1000(包含0和1000).

输入描述:
输入包含两部分:
第一行M, N
接下来M行,包含N个平安果数量

输出描述:
一个整数
最多拿走的平安果的数量

示例:

输入
2 4
1 2 3 40
6 7 8 90

输出
136
*/

//这是josan的AC代码,仅供参考。
//程序有什么bug,有什么可以改进的地方,欢迎私信交流或者留言回复。
//共同学习,共同进步。

#include <vector>
#include <iostream>
using namespace std;

//一道简单的dp问题
int main()
{
#if 1
	freopen("in.txt", "r", stdin);
#endif
	int m, n;
	while(cin >> m >> n)
	{
		vector<vector<int>> ivec(m, vector<int>(n));
		for(int i = 0; i < m; ++i)
		{
			for(int j = 0; j < n; ++j)
			{
				cin >> ivec[i][j];
			}
		}
		vector<vector<int>> dp(ivec);
		//--------预处理
		//初始化dp第一列
		for(int i = 1; i < m; ++i)
		{
			dp[i][0] += dp[i - 1][0];
		}
		//初始化dp第一行
		for(int j = 1; j < n; ++j)
		{
			dp[0][j] += dp[0][j - 1];
		}
		//计算dp的其他部分
		for(int i = 1; i < m; ++i)
		{
			for(int j = 1; j < n; ++j)
			{
				//原始dp[i][j]==ivec[i][j],所以这里没有另外再加+ivec[i][j]
				dp[i][j] += (dp[i - 1][j] < dp[i][j - 1]) ? dp[i][j - 1] : dp[i - 1][j];
			}
		}
		cout << dp[m - 1][n - 1] << endl;
	}
	return 0;
}

//以下为自己提交代码,想的直接用递归求解,但是如果数据量很大的话,这种方法容易爆栈。
//int getAppleIn(vector<vector<int> >& ivec, int m, int n, int row, int col)
//{
//	if(row >= m||col >= n)
//	{
//		return 0;
//	}
//	else if(row == m - 1)
//	{
//		int sum = 0;
//		for(int i = col; i < n; ++i)
//		{
//			sum += ivec[row][i];
//		}
//		return sum;
//	}
//	else if(col == n - 1)
//	{
//		int sum = 0;
//		for(int i = row; i < m; ++i)
//		{
//			sum += ivec[i][col];
//		}
//		return sum;
//	}
//	else
//	{
//		int sum = ivec[row][col];
//		int sum1 = getAppleIn(ivec, m, n, row + 1, col);
//		int sum2 = getAppleIn(ivec, m, n, row, col + 1);
//		return sum + (sum1 < sum2 ? sum2 : sum1);
//	}
//}
//
//int getApple(vector<vector<int> >& ivec, int m, int n)
//{
//	int sum = getAppleIn(ivec, m, n, 0, 0);
//	return sum;
//}
//
//int main()
//{
//#if 1
//	freopen("in.txt", "r", stdin);
//#endif
//	int m, n;
//	vector<vector<int>> ivec;
//	while(cin >> m >> n)
//	{
//		for(int i = 0; i < m; ++i)
//		{
//			vector<int> tem;
//			for(int j = 0; j < n; ++j)
//			{
//				int num;
//				cin >> num;
//				tem.push_back(num);
//			}
//			ivec.push_back(tem);
//		}
//		int res = getApple(ivec, m, n);
//		cout << res;
//	}
//	return 0;
//}


华为机试总结

本次机试总结,第一题常规题,可以说是送分题。第二题难点,任务的具体个数没有告诉你,还有输入输出都需要对逗号进行处理,(我当初天真地忽略输入的逗号,真是亏了),主要相同优先级的情况。第三题,一个典型的动态规划问题。当时做的时候,时间比较紧,立马写了一个第一个进入脑中的思路--递归。

另外,也做了牛客网的华为的一些机试题目,整体来说,华为的机试属于偏简单的题目。好好做,一般是能够三题AC的。

有些细节分享一下:

  • 对于输入输出的限定比较严格,尤其本次笔试的第二题,输入必须要有逗号的处理。类似的情况也发生在校招实习的时候。

华为2018届校招勇敢星实习生招聘笔试+面试经历

http://blog.csdn.net/jacky_chenjp/article/details/73433824

  • 华为的题目,测试数据一般都是比较小的,而且测试数据一般不是很全(比如:我的AC第一题的程序是有漏洞的,但是没有测出来)。

这就意味着,只要有思路,哪怕是暴力,很有可能就AC了


总而言之,感觉华为更看重你的项目经历,经验。一般笔试不会卡人。而且你三题AC跟两题AC进去面试是一样的效果。因为面试官不会跟你讨论笔试的内容,他们认为能进去面试的人的编码能力都已经合格。另外,听说华为进去之后,还会要求继续刷OJ,或者这也是华为为什么不看重你写的代码的质量吧。华为的老总应该认为这种东西,集中刷刷,能达到中等要求就行。关键是你来公司,要立马能创造劳动价值。


最后,祝大家18秋招顺利!


  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值