这次参加了场华为的网上笔试,三个算法题,难度还是比较简单的
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; }
总体来说,华为的软件工程师的校招面试题难度偏中等,没有经过练习的话,可能只能写出一个题
算法题在面试中还是很热门的考点,而网上面试几乎都有算法题,希望大家多加学习,我也会继续更新算法题部分的