華為2018屆校園招聘筆試題目以及相應程式碼分享 軟體開發崗位
阿新 • • 發佈:2019-01-05
華為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的。
有些細節分享一下:
- 對於輸入輸出的限定比較嚴格,尤其本次筆試的第二題,輸入必須要有逗號的處理。類似的情況也發生在校招實習的時候。
http://blog.csdn.net/jacky_chenjp/article/details/73433824
- 華為的題目,測試資料一般都是比較小的,而且測試資料一般不是很全(比如:我的AC第一題的程式是有漏洞的,但是沒有測出來)。
這就意味著,只要有思路,哪怕是暴力,很有可能就AC了
總而言之,感覺華為更看重你的專案經歷,經驗。一般筆試不會卡人。而且你三題AC跟兩題AC進去面試是一樣的效果。因為面試官不會跟你討論筆試的內容,他們認為能進去面試的人的編碼能力都已經合格。另外,聽說華為進去之後,還會要求繼續刷OJ,或者這也是華為為什麼不看重你寫的程式碼的質量吧。華為的老總應該認為這種東西,集中刷刷,能達到中等要求就行。關鍵是你來公司,要立馬能創造勞動價值。
最後,祝大家18秋招順利!