华为2014校园招聘机试题

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");
		else
			printf("%d\n", arr[n - 1]);
	}

	return 0;
}
第三题解析:
其实这是一个深搜问题,不过呢,你可以看到题目截图中有答案提示:城市数目较多,因此不能使用完全遍历,无法满足时间复杂度要求。所以需要对数据做一下预处理,也就是将map转换为链表形式的,本来map应该是只有0,1的值,表示有路径或者没路径。不过为了节约点内存(虽然没什么必要),所以map复用。当前节点i如果和另外的节点j相连,则将节点j放在map中。第0个元素存放当前访问到第几个节点(从1开始,深搜回溯的时候有用),后面依次存放与之相邻的节点,最后以-1结束。
map转化完成之后,剩下的就是深搜了。不明白?直接看代码吧。想到那个scanf的错误,我现在都伤心啊......
#include
#include

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 while
		
		printf("%d\n", ans);		
	}

	return 0;
}
贴出三道题的题目图片:
题目编号一次为1,2,3;
华为2014校园招聘机试题_第1张图片 华为2014校园招聘机试题_第2张图片 华为2014校园招聘机试题_第3张图片
























你可能感兴趣的:(面试笔试)