本文由CSDN-蚍蜉撼青松【主页:http://blog.csdn.net/howeverpf】原创,转载请注明出处!
写在前面:
当前华为公司的一次机试,共三道不同难度的编程题(其中,初级题60分、中级题100分、高级题160分),机试成绩>=60即可参加下一轮面试。一定程度上说,只要完全做对初级题,就可以通过机试的考验。当然,这样的通过肯定不太利于后面的面试。
写作本文的目的有两个,一是对本次参加的华为公司机试做个整理和小结,属于自我提升;二是让各位求职的应届生同道能够直观体验当前一般的机试题大概是何种类型,难度又有几分,属于经验分享。由于只是作为体验而非试题汇总,所以本文只列举了我以及我的小伙伴们遇到的几次机试中的初级题,并不做更多的收集。
每道题包括题目详情、编程思路、代码实现三部分。
1、输出重复的英文字符
编程思路:
先遍历一次整个输入字符串,分别记录所有出现过的字符(剔除重复的,按字符第一次出现位置的先后排列。用数组cExistChar)以及他出现的次数(为了操作方便,可以用分配排序的思想。用数组nApperTimes);
再遍历一次数组cExistChar,若其出现次数大于1,则输出。
代码实现:
[cpp] view plaincopyprint?
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define MAX_IN_SIZE 1000 // 输入字符串的最大长度
-
- int print_repeat_chars(char *pszString)
- {
- char cExistChar[52]; // 所有出现过的字符(剔除重复的|最多52个)
- int nExistCharCount = 0; // 当前一共出现了多少不重复的字符
- int nApperTimes[52]; // 所有英文字符出现过的次数(基于分配排序思想,以英文字符的值的某种运算结果作为下标)
- int i,nStrLen = 0;
- char temp;
-
- memset(nApperTimes, 0, sizeof(nApperTimes));
-
- // 遍历整个输入字符串
- nStrLen = strlen(pszString);
- for(i=0; i<nStrLen; i++)
- {
- temp = *(pszString+i);
- if( temp>='A' && temp<='Z')
- {
- // 大写英文字符是否是第一次出现
- if(nApperTimes[temp-'A']==0)
- {
- // 记录前面没出现过的新大写英文字符
- cExistChar[nExistCharCount++] = temp;
- }
- nApperTimes[temp-'A']++;
- }
- else if( temp>='a' && temp<='z')
- {
- // 小写英文字符是否是第一次出现
- if(nApperTimes[temp-'a'+26]==0)
- {
- // 记录前面没出现过的新大写英文字符
- cExistChar[nExistCharCount++] = temp;
- }
- nApperTimes[temp-'a'+26]++;
- }
- //只处理52个大小写英文字符,其余字符不处理
- }
-
- // 遍历cExistChar
- for(i=0; i<nExistCharCount; i++)
- {
- temp = cExistChar[i];
- if( temp>='A' && temp<='Z')
- {
- // 输出出现次数大于1的大写字符
- if(nApperTimes[temp-'A']>1)
- printf("%c", temp);
- }
- else if( temp>='a' && temp<='z')
- {
- // 输出出现次数大于1的小写字符
- if(nApperTimes[temp-'a'+26]>1)
- printf("%c", temp);
- }
- }
-
- return 0;
- }
-
- int main(void)
- {
- char szInString[MAX_IN_SIZE]; //输入字符串
-
- // 获取输入的字符串
- scanf("%s", szInString);
- // 打印输入字符串中重复的英文字符
- print_repeat_chars(szInString);
-
- return 0;
- }
2、笨笨熊搬家打包篇
| |
---|
| |
| |
| 整数V——纸盒的容积;
整数N——物品的总数目N;
共N个整数(对应N个物品的体积,每个整数用空格隔开)。 |
| |
| |
| |
编程思路:
先把所有物品按体积从大到小排个序。
然后用两个指针分别从头、尾向中间遍历,直到头指针与尾指针重合,或超过尾指针。在遍历的过程中,对于头指针,恒速后推;对于尾指针,取当前头、尾指针指向的物品(即当前剩余物品中体积最大和最小的物品),体积求和,若小于盒子的体积,则尾指针前移一位。
若头、尾指针重合,则最少所需盒子数为头指针的位移量+1;若头指针超过了尾指针,则最少所需盒子数为头指针的位移量。
代码实现:
[cpp] view plaincopyprint?
- #include <stdio.h>
- #include <stdlib.h>
-
- #define ITEMS_COUNT_MAX 100
-
- // 冒泡降序排序
- //参数 pSortList, 待排序序列
- int my_sort_bubble(int *pSortList, int nListSize)
- {
- int i,j;
- bool bIfContinue = true; //外循环继续标志(如果你要写纯C程序,当然就需要把这里替换成整型)
-
- for(i=0; i<nListSize-1 && bIfContinue; i++) //bIfContinue为false时,直接退出外循环
- {
- bIfContinue = false; //内循环开始前假定i后面的子序列已经完全有序,外循环继续标志置为false
-
- // 从最后一个元素开始,直到第 i+1 个元素
- // 所有元素依次和它的前一个元素作关键字比较,更大则交换
- for(j=nListSize-1; j>i; j--)
- {
- if(pSortList[j] > pSortList[j-1]) //冒泡排序比小,咱比大
- {
- bIfContinue=true; //只要有一次元素交换,说明未完全有序,则外循环需要继续
-
- pSortList[j] = pSortList[j] + pSortList[j-1];
- pSortList[j-1] = pSortList[j] - pSortList[j-1];
- pSortList[j] = pSortList[j] - pSortList[j-1];
- }
- }
- }
-
- return 0;
- }
-
- // 计算最少所需盒子数
- //参数 nVolume_of_box, //盒子的容积V
- //参数 nNum_of_items, //物品的数量N
- //参数 pnVolume_of_items, //N个物品的体积
- //返回 最少所需盒子数
- int calc_least_box_count(int nVolume_of_box, int nNum_of_items, int *pnVolume_of_items)
- {
- int i,j;
-
- if(nNum_of_items <= 1)
- return nNum_of_items;
-
- // 先对所有物品的体积从大到小排序
- my_sort_bubble(pnVolume_of_items, nNum_of_items);
-
- // 输入合法性判定,不可能有体积大于盒子容积的物品
- if(pnVolume_of_items[0] > nVolume_of_box)
- return -1;
-
- // 物品体积等于盒子容积时,必然单独占一个盒子
- for(i=0; pnVolume_of_items[i] == nVolume_of_box; i++)
- ;
-
- j = nNum_of_items-1;
- for(; i<j; i++)
- {
- // 小物品和大物品的体积和若小于盒子容积,则小物品不单独使用盒子
- if(pnVolume_of_items[i]+pnVolume_of_items[j] <= nVolume_of_box)
- j--;
- }
-
- if(i == j)
- return i+1;
-
- return i; // i > j
- }
-
- int main(void)
- {
- int nVolume_of_box; //盒子的容积V
- int nNum_of_items; //物品的数量N
- int *pnVolume_of_items; //N个物品的体积
- int i;
-
- scanf("%d", &nVolume_of_box); //获取盒子容积
- scanf("%d", &nNum_of_items); //获取物品数量
-
- pnVolume_of_items = (int*)malloc(nNum_of_items * sizeof(int)); //根据物品数量创建存储空间
- for(i=0; i<nNum_of_items; i++)
- scanf("%d", &pnVolume_of_items[i]); //挨个录入物品的体积(特别注意勿忘取地址符)
-
- printf("%d", calc_least_box_count(nVolume_of_box, nNum_of_items, pnVolume_of_items));
-
- return 0;
- }
3、出租车计费(测试模拟题)
| |
---|
| |
| |
| 输入公里数(浮点数)和时间(整数,单位分钟),以空格隔开 |
| |
| |
| |
编程思路:
分别以里程、时间为依据计算收费,取二者中的较大值。
代码实现:
[cpp] view plaincopyprint?
- #include <stdio.h>
-
- int main(void)
- {
- float fDistance; // 里程
- int nTime; // 时间
- float fPrice1=6.0,fPrice2=6.0; // 两种不同计费方式的费用值
- int n;
-
- // 获取输入的里程和时间
- scanf("%f %d", &fDistance, &nTime);
-
- if(fDistance<=2.0 && nTime<=10)
- printf("6.0"); // 满足起步价条件,fPrice1=fPrice2=6.0
- else
- {
- // 若里程数大于2公里,需要另外计算 fPrice1
- if(fDistance>2.0)
- {
- n = (int)((fDistance-2.0)/0.5); // 显式取整,因为不足0.5公里不计费
- fPrice1 += n*0.7;
-
- // 若里程数大于7公里,需要附加返程费
- if(fDistance>7.0)
- {
- n = (int)(fDistance-7.0); // 显式取整,因为不足1公里不计费
- fPrice1 += n*0.7;
- }
- }
-
- // 若时间大于10分钟,需要另外计算 fPrice2
- if(nTime>10)
- {
- n = (nTime-10)/3; // 隐式取整,因为不足3分钟不计费
- fPrice2 += n*1.4;
- }
-
- // 打印两种计费方式产生的费用值中的较大值
- printf("%.1f", fPrice1>fPrice2?fPrice1:fPrice2);
- }
-
- return 0;
- }