华为2014校园招聘机试题

来源:互联网 发布:手机淘宝商品图片尺寸 编辑:程序博客网 时间:2024/05/16 08:40
2013.10.9 上午9:00开始
先吐槽一下,学校的机房。我严重怀疑学校机房的VS2010是不是坏的,折腾了半天,一个测试的hello world程序都不能跑。最后,二十多分钟之后,我放弃了,果断选择了VC6.0.虽然很多东西编译不过,但是没办法啊。唉,结果最后人家性格测试都做完了,我才做了1/3。性格测试就不吐槽了。
OK,废话不多说了,本来是可以三道题都做完的,结果最后一道题,scanf的时候,scanf("%d", &map[i][j]);写成了scanf("%d", &map);回来才发现的啊,我都想扇自己两下。(咳咳,貌似有点暴力了)。觉得好的话,默默顶一下?妹纸码字也不容易哈~
第一题解析:
其实就是排序算法嘛,直接快排,比较好些,效率也可以,没什么好说的。这道题的难点在于输入的时候,是以字符串形式输入,然后事先不知道当前这一次排序有多少个数字,所以需要一点技巧。废话不多说,直接上代码,时间紧急,可能不是很漂亮。
void quickSort(int *arr, int nLen){if(arr == NULL || nLen < 1)return;int Begin = 0;int End = nLen - 1;int key = arr[Begin];while(Begin < End){while(Begin < End && arr[End] >= key)--End;if(Begin < End)arr[Begin++] = arr[End];while(Begin < End && arr[Begin] < key)++Begin;if(Begin < End)arr[End--] = arr[Begin];}arr[Begin] = key;quickSort(arr, Begin);quickSort(arr + Begin + 1, nLen - Begin - 1);}void Print(int *arr, int nLen){if(arr == NULL || nLen < 1)return;printf("%d", arr[0]);for(int i = 1; i < nLen; ++i){printf(",%d", arr[i]);}printf("\n");}int main(){const int max_len = 1030;const int size = 130;char str[max_len];int arr[size];int nLen,i;while(gets(str)){nLen = 0;i = 0;while(str[i] != '\0'){sscanf(&str[i], "%d", &arr[nLen]);++nLen;while(str[i] != '\0' && str[i] != ',')++i;if(str[i] == ',')++i;}quickSort(arr, nLen);Print(arr, nLen);}return 0;}
第二题解析
这个丑数,也没什么好说的。我写的是最2的一种方法,当然可以用3个队列进行优化。其实题目变一下,就是一个OJ的题,比如说,求因子只有{2,3,5,7}的第n个数是多少。最好用队列解,效率高。这里,由于数字可能比较大,所以需要用unsigned long long类型,不过坑爹的VC6.0是不能编译过的,害得我写好了发给别人远程帮我编译一下,好坑!上代码:
bool IsTrue(unsigned long long num){while(num % 2 == 0)num /= 2;while(num % 3 == 0)num /= 3;while(num % 5 == 0)num /= 5;return num == 1;}int main(){const int size = 501;unsigned long long arr[size];unsigned long long base = 1;int count = 0;while(count < size){if(IsTrue(base)){arr[count++] = base;}++base;}int n;while(scanf("%d", &n) != EOF){if(n < 1 || n > 500)printf("-1\n");elseprintf("%d\n", arr[n - 1]);}return 0;}
第三题解析:
其实这是一个深搜问题,不过呢,你可以看到题目截图中有答案提示:城市数目较多,因此不能使用完全遍历,无法满足时间复杂度要求。所以需要对数据做一下预处理,也就是将map转换为链表形式的,本来map应该是只有0,1的值,表示有路径或者没路径。不过为了节约点内存(虽然没什么必要),所以map复用。当前节点i如果和另外的节点j相连,则将节点j放在map中。第0个元素存放当前访问到第几个节点(从1开始,深搜回溯的时候有用),后面依次存放与之相邻的节点,最后以-1结束。
map转化完成之后,剩下的就是深搜了。不明白?直接看代码吧。想到那个scanf的错误,我现在都伤心啊......
#include<stdio.h>#include<string.h>int main(){const int N = 10;int map[N][N];int stack[N];bool visited[N];int n,a,b;int Begin;int i,j;while(scanf("%d %d %d", &n, &a, &b) != EOF){for(i = 0; i < n; ++i){for(j = 0; j < n; ++j){scanf("%d", &map[i][j]);}}for(i = 0; i < n; ++i){int index = 0;map[i][0] = 1;for(j = 0; j < n; ++j){if(map[i][j] && i != j)map[i][++index] = j;//记录下可达的点}map[i][++index] = -1;//-1结束}//深搜memset(visited, 0, N * sizeof(bool));int top = -1;int ans = 0;stack[++top] = a;//a入栈visited[a] = true;while(top > -1)//栈不空{Begin = stack[top];//取栈顶元素for(i = map[Begin][0]; map[Begin][i] != -1; ++i){if(map[Begin][i] != b && !visited[map[Begin][i]])//未访问过{stack[++top] = map[Begin][i];visited[map[Begin][i]] = true;map[Begin][0] = i + 1;break;}if(map[Begin][i] == b)++ans;}if(map[Begin][i] == -1)//这个点的所有路径都走过了,退栈{--top;}}// end for whileprintf("%d\n", ans);}return 0;}
贴出三道题的题目图片:
题目编号一次为1,2,3;