華為2018屆校園招聘筆試題目以及相應程式碼分享 軟體開發崗位

lizi_stdio發表於2017-08-03

華為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秋招順利!


相關文章