這次參加了場華為的網上筆試,三個算法題,難度還是比較簡單的
A
給一個N*N的數組,問你順時針旋轉M次之后的數組
比如
1 2 3
4 5 6
7 8 9
旋轉一次是
7 4 1
8 5 2
9 6 3
兩次是
9 8 7
6 5 4
3 2 1
只要換一種方式輸出數組即可
#include<bits/stdc++.h> #define LL long long #define maxn 100010 using namespace std; int s[110][110], ans[110][110]; int main(){ int n; scanf("%d", &n); for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ scanf("%d", &s[i][j]); } } int m; scanf("%d", &m); m = m % 4; if(m == 0){ for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ printf("%d", s[i][j]); if(j != n - 1){ printf(" "); } } printf("\n"); } } else if(m == 1){ for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ printf("%d", s[n - j - 1][i]); if(j != n - 1){ printf(" "); } } printf("\n"); } } else if(m == 2){ for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ printf("%d", s[n - i - 1][n - j - 1]); if(j != n - 1){ printf(" "); } } printf("\n"); } } else if(m == 3){ for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ printf("%d", s[j][n - i - 1]); if(j != n - 1){ printf(" "); } } printf("\n"); } } return 0; }
B
給m個小孩子分n個糖,問方案及每種方案的做法
比如給2個小孩分三個糖,一個拿1個,一個拿兩個的分法表示成 *|**
方案數肯定就是C(n+m, m)
很簡單,深搜方案即可,好像clang交會爆棧,但是最后改提交語言過了
#include<bits/stdc++.h> #define LL long long #define maxn 100010 using namespace std; int now[20]; int n, m; void _dfs(int h, int t){ if(t == m - 1){ int sum = 0; for(int i = 0; i < t; ++i){ for(int j = 0; j < now[i]; ++j){ printf("*"); sum++; } printf("|"); } for(int i = sum; i < n; ++i){ printf("*"); } printf("\n"); } else{ for(int i = h; i >= 0; --i){ now[t] = i; _dfs(h - i, t + 1); } } } int main(){ scanf("%d %d", &n, &m); int cs = 1; for(int i = 1; i < m; ++i){ cs = cs * (n + i); cs = cs / i; } printf("%d\n", cs); _dfs(n, 0); return 0; }
C
有N個字符串,給你改之前的和改之后的,問你最少改(增,刪,改)幾次
就是N遍LCS唄,nlogn的復雜度,答案累加N次即可
LCS的板子我網上找的,應該沒啥問題
#include <bits/stdc++.h> #define LEN 20010 #define LL long long using namespace std; string aa[LEN], bb[LEN]; string a, b; int loc[LEN], n; void calLoc(){ int i; for(i = 0; i <= n; i++){ loc[int(b[i])] = i; } } int LIS(){ int i, k, l, r, mid; a[0] = b[0], k = 0; for(i = 1; i < n; i++){ if(a[k] < b[i]){ a[++k] = b[i]; } else{ l = 0; r = k; while(l <= r){ mid = (l + r) / 2; if(a[mid] < b[i]){ l = mid + 1; } else{ r = mid - 1; } } a[l] = b[i]; } } return k; } int main(){ int T; scanf("%d", &T); int ans = 0; for(int i = 0; i < T; ++i){ cin >> aa[i]; } for(int i = 0; i < T; ++i){ cin >> bb[i]; } for(int i = 0; i < T; ++i){ a = aa[i]; b = bb[i]; n = max(a.size(), b.size()); for(int i = a.size(); i < n; ++i){ a.push_back(' '); } for(int i = b.size(); i < n; ++i){ b.push_back(' '); } calLoc(); for(int i = 1; i <= n; i++) b[i] = loc[int(a[i])]; ans = ans + n - LIS(); } printf("%d\n", ans); return 0; }
總體來說,華為的軟件工程師的校招面試題難度偏中等,沒有經過練習的話,可能只能寫出一個題
算法題在面試中還是很熱門的考點,而網上面試幾乎都有算法題,希望大家多加學習,我也會繼續更新算法題部分的