大师兄教你怎样过华为机试
宝典1—内功心法
大华为这个大数据时代土豪金海量式的招聘又要開始了!
最近听说大华为的校招机试立即就要開始了,因为华为软件岗位的招聘仅仅有技术面跟机试是与技术有关的内容,所以机试的地位非常重要。对于机试,除了长期积累的软件基本功以外,还有非常多能够短期训练的东西,类似于考试之前的袭击。能够迅速提高机试成绩,就像在我西电大杨老师考前最后一堂课一定要去。那个重点就是考点阿。
这篇机试葵花宝典的内容是针对华为软件类上机准备的。假设你认真看了本宝典,假设你是真正通过自己能力考上西电的话,想只是都难。
对于机试,首先应该调整好自己的心态,不要认为敲代码非常难。机试题非常难,也不要去考虑。万一机试考到自己不会的内容怎么办。要相信,机试题永远是考察每一个人的基础。基础是不会考的非常偏的,会有人恰好做过某个题而做出来那个题,但不会有人恰好没做过一个题而做不出来那个题。
机试之前,应该做的准备有:
1、 买一本《算法竞赛入门经典》,这本书不同于普通的算法或者编程语言的书籍。这本书既讲语言,又讲算法。由浅入深。讲的非常好,能看完前几章而且把例题都做会。想通过机试就非常easy了
2、 调整好心态。时刻告诉自己,哪些小错误是自己曾经常常犯的。最好用笔记本记录下来,写每道题前再看一遍。假设遇到代码调不出来了,先想想自己是否犯过曾经那些错误。还有就是,看了题目以后。先细致想清楚细节,在纸上写清楚自己须要用到的变量,以及代码的基本框架,不要急于动手去写代码
3、 不要惧怕不论什么一道看起来非常难的题目,有不会的就去问身边会的人,让别人给自己讲清楚
4、 心中默念10遍C++跟C除了多了两个加号事实上没有差别,会C就能上手C++
5、 大量的练习是必要且有效的
6、 看完这篇宝典,预过机试、必练此功。
在这里推荐一个帖子,是机试归来的学长写的,写的非常不错,里面的例题在后面的攻略中也会提及, 就在好网上。
宝典二:经常使用招式
1:机试经常使用变量类型
CC++经常使用的变量类型有非常多种,想通过机试,掌握好当中的几种就能够,他们各自是int。double, string, char[]
int 类型是最经常使用的整数类型,对于输入类型是整形的变量,使用int来进行定义和读入。另一种更大的整形变量是long long。在机试中一般不会涉及到考察,假设考虑到运算的过程中有可能超过int的大小。再考虑使用long long。int最大能够到达2^31级别,long long最大能够到达2^63。
PS:有时机试读入多个整数的时候会是这种形式
5,10
中间有一个逗号,在这样的情况下。事实上读入也是非常easy的,能够这么写:
scanf(“%d%c%d”,&a,&b,&c);
或者是:
scanf(“%d”,&a);
getchar();
scanf(“%d”,&c);
有的机试题会说:两个整数之间有若干个空格符或tab字符。在这样的情况下,读入的方式还是使用scanf(“%d%d”,&a,&b)这样,scanf函数或者cin函数都能够非常好的吃掉除了数字字符以外的字符。
double类型是最经常使用的浮点数类型,当运算涉及到小数运算的时候。须要使用double来定义。当中。特别须要注意的一点是。假设使用了例如以下语句:
double x=a/b;
在这里。a和b是int。那么x的值将是a和b整除后的结果,而不是想要的结果,想要得到期望的结果,须改成
double x=(a+0.0)/b;
在这里。将a加上一个浮点数,程序会在后台将它强制转换成一个double类型的数字。此时再除一个整数,就没有问题了
string类型是遇到字符串类问题应该首选的变量,差别于字符数组char[]。string类型是直接将字符数组封装了进去,定义string s相当于定义了一个大小特别长的字符数组。使用string的优点是,避免了使用char数组时定义数组长度过小导致越界,同一时候更加直观的将字符串看做了一个对象。
假设要定义一个string变量,首先得包括string的头文件以及使用C++中的标准命名空间,标准命名空间这个东西,仅仅要记得写上即可,没有不论什么影响。
#include<iostream> //这一句是c++的头文件,c语言代码一样能够把它包括进来,仅仅要将程序后缀名改成.cpp就可以。其它都是一样的。
#include<string.h>
using namespace std;
在不同的环境下。可能会有不同的头文件包括了string的使用方法,可能的头文件有cstring,string。在机试的环境中,一般使用string.h就可以。
定义一个string和定义其它变量方式同样:
string s;
读入和输出string也仅仅须要使用
cin>>s;
cout<<s;
这是比c语言的字符数组要简单了非常多的。
须要注意的是,string类型读入的时候与char数组的scanf读入一样,都是遇到空格符或者回车符就停止读入,当做一个完整字符串来处理,因此。使用string处理带空格的字符串是不明智的,其它情况下是都能够的。
string变量包括了非常多强大的功能,如:
[cpp] view plaincopyprint?
1. s[i]; //这么写。返回的就是字符串s第i+1位的字符,返回的类型是char型,当中,s[0]是它的第一位,与字符串同样。
2. s.size(); //返回字符串的长度,返回的长度是l,则s从s[0]到s[l-1]表示的是其每一位的字符。
3. if (s1<s2) //两个string是能够方便的使用大小于符号以及等于号来比較大小的。比較的方式是,从左向右按位进行比較。每一位依照字典序来比較。如”aaaa”<”abc”<”bcd”,但值得注意的一点是。比較的时候应用变量进行比較,即s1<s2这样的,而不能用”aa”<”bb”这样。假设要比較他俩的大小,应这么写:
4. s1="aa"; s2="bb";
5. if (s1<s2)
string类型还有非常多强大的功能,可是对于机试来说,会使用以上三种功能就足够了。
char[50],char[100]这样的字符数组与string类型非常像,仅仅只是他是C语言里面的使用方法。对于机试,仅仅建议在输入带有空格字符的字符串时使用char数组。使用的方式是:
gets(s);
在这里。gets函数差别于scanf函数的是,gets函数会直接将一整行读进来,而不会遇到空格就停下来。
常见机试题类型
0基础题常见的类型无非就是字符串处理类的题目和数字处理类的题目。在这里归结例如以下:
1:字符串处理类
字符串全部大写转小写:
1. for (int i=0;i<s.size();i++)
2. if (s[i]>=’A’ && s[i]<=’Z’)
3. s[i]=s[i]-’A’+’a’;
//s[i]-’A’返回的是两个大写字母之间的差值,比方’C’与’A’的差值是2,这个差值是一个int类型,也能够直接提取出来使用。给这个差值再加上字母’a’。相当于给’a’再往后推移二位,变成字母’c’。这样的使用方法是字符串内最普遍的一种使用方法。小写转大写也是一样。
删除满足指定要求的字符后输出:
在机试中,判定对错的方式是比較输出的结果。而非检查内部的结果。因此,“删除”对于机试来说,相当于“不输出”,也就是说。不须要调用s.erase()函数,仅仅须要在遇到被删除的字符时。跳过,不输出就可以。
1. for (int i=0;i<s.size();i++)
2. {
3. if (s[i]满足删除要求) 跳过;
4. else 输出s[i];
5. }
倒转字符串:
与删除字符串的思路类似,倒转一个字符串,事实上就是倒着输出,仅仅须要将循环反过来就能够。
1. for (int i=s.size()-1;i>=0;i--)
字符串比較大小:
假设比較的规则与字符串的比較规则同样。则直接使用s1>s2这样的方式,假设规则不同,则用一重循环按位比較就可以。
2、数字处理类
数字处理类的题目,最常见的两种考察形式是整数拆分、进制转换和排序。
整数拆分是指将一个整数拆分开每一位。比方123拆分成1,2,3。整数拆分的思路有两种,第一种是直接用字符串读入。然后把每一位用字符的形式提取出来:
[cpp] view plaincopyprint?
1. for (int i=0;i<s.size();i++)
2. <span style="white-space:pre"> </span>num[i]=s[i]-'0';
另一种思路是不断去除以10。把余数提取出来。方法是:
[cpp] view plaincopyprint?
1. while (n!=0)
2. {
3. <span style="white-space:pre"> </span>num[i]=n%10;
4. <span style="white-space:pre"> </span>n=n/10;
5. <span style="white-space:pre"> </span>i++;
6. }
进制转换:
进制转换又分为10进制转换成别的进制以及别的进制转换成10进制,进制转换事实上特别简单。仅仅须要记住例如以下代码:
10进制转换成X进制
[cpp] view plaincopyprint?
1. while (n!=0)
2. {
3. <span style="white-space:pre"> </span>num[i]=n%x;
4. <span style="white-space:pre"> </span>i++;
5. <span style="white-space:pre"> </span>n=n/x;
6. }
X进制转换成10进制
[cpp] view plaincopyprint?
1. for (int i=0;i<=length;i++)
2. {
3. ans=ans*x+num[i];
4. }
当中,num[i]表示的是该x进制数的每一位,比方一个二进制数101。用这样的转换方式去转换。ans的值从i=0到i=2处理后各自是1,2,5。
排序:
排序这个东西。事实上不须要学习冒泡啊、快排啊之类的算法,应对机试,C++中自带的sort函数就能够非常好的解决,请看以下一段代码
[cpp] view plaincopyprint?
1. </pre><pre name="code" class="cpp">#include<iostream>
2. #include<algorithm> //这个是包括sort函数的头文件
3. using namespace std;
4. int arr[100],n;
5. int cmp(int x,int y) //这个函数是sort函数比較两个元素优先级的函数。在这里计算出两个元素的优先级,然后返回就可以。
6. {
7. int importance1,importance2;
8. //此处插入代码计算x,y的重要性
9. return importance1<importance2; //此处返回小于号。意思是优先级小的在前。如return x<y;则数组会由小到大排序
10. }
11. int main()
12. {
13. cin>>n;
14. for (int i=0;i<n;i++) cin>>arr[i];
15. sort(arr,arr+n,cmp);
16. return 0;
17. }
这一段代码的作用是读入n个数字,然后按优先级进行排序,排序的比較方法在cmp函数中实现,排序的详细过程不须要考虑。
能够看到。事实上仅仅须要记住sort函数的使用方法,要通过机试,排序算法是根本不须要学习的,so easy!
总结:机试中。掌握好int。double,string。char[],还有数组,就足够用了,但考察的内容不不过上述这些,想要通过机试,还是应该多多练习,多多学习,不局限于上面所说的内容
宝典三:擂台实战
首先推荐一个站点:acm.xidian.edu.cn/land/,上面的非常多题目,难度非常适合机试,如:
非常easy:1031,1120,1122,1121,1103,1104,1281,
简单:1049,1181,1182,1279,1280。
中等:1106,1108,1183,1288.
难:1105,1282,1283,
大家能够依据自己的水平去训练,事实上里面的难题也是非常easy的,归类到题库中的话都属于简单题,仅仅要好好看书学习都是能够做出来的,以下放几道例题,这些题都是机试非常有可能考的题目,或者是非常类似的题目。已经有了细致的凝视,代码写的仓促
1. 简单题
2. 题目描写叙述
3. 输入一个字符串,删除当中全部的数字,全部大写字母改成小写,其它不变。并输出
4.
5. 输入描写叙述
6. 一个字符串,保证没有空格。以回车符结束。字符串长度<=20
7. 输出描写叙述
8. 一个字符串。为题目要求的结果
9.
10. 输入例子
11. aAbB13A
12. 输出例子
13. aabba
14.
15. 解题思路:模拟题目要求就可以,遇到数字就跳过不输出,遇到大写字母就改成小写。
16.
17. */
18. #include<iostream>
19. #include<string.h>
20. using namespace std;
21. int main()
22. {
23. string s;
24. cin>>s;
25. for (int i=0;i<s.size();i++) //枚举字符串的每一位
26. {
27. if (s[i]>='0' && s[i]<='9') continue; //遇到数字就跳过
28. if (s[i]>='A' && s[i]<='Z') s[i]=s[i]-'A'+'a'; //遇到大写字母就改成小写
29. cout<<s[i];
30. }
31. cout<<endl;
32. }
33. </span>
34. 简单题
35. 题目描写叙述
36. 输入一个字符串,统计其出现频率最高的字符,并输出。若存在两个字符出现频率同样,则输出字典序较小的那一个
37.
38. 输入描写叙述
39. 一个字符串,保证没有空格,以回车符结束,字符串长度<=20
40. 输出描写叙述
41. 一个字符
42.
43. 输入例子
44. aabbaabb
45. 输出例子
46. a
47.
48. 解题思路:做一个频率数组来统计全部字符的出现频率,机试时候不会有汉字输入。因此仅仅考虑输入是ASCII编码的情况。
49.
50. */
51. #include<iostream>
52. #include<string.h>
53. using namespace std;
54. int f[200]; //频率数组
55. int biggest=0; //记录最大的值
56. int main()
57. {
58. memset(f,0,sizeof(f)); //将f中的所有元素变成0,写循环也可
59. string s;
60. cin>>s;
61. for (int i=0;i<s.size();i++) //枚举字符串的每一位
62. {
63. int num=s[i]; //将s[i]转换成它的ascii码
64. f[num]++; //频率次数加1
65. biggest=max(biggest,f[s[i]]); //比較找出最大的
66. }
67. for (int i=0;i<=129;i++) //枚举全部的字符的频率,找出频率最高且字典序最小的那一个
68. if (f[i]==biggest) //假设满足要求
69. {
70. cout<<(char)(i)<<endl;
71. break; //这句break保证了我们仅仅会输出一个满足要求的结果
72. }
73. }
74. /*
75. 简单题
76. 题目描写叙述
77. 输入一个数字,将其倒序输出。并输出其各个位上的乘积
78.
79. 输入描写叙述
80. 一个正整数,保证在int范围内
81. 输出描写叙述
82. 两个数字,用空格隔开。第一个数字为其倒序的值,第二个数字是各个位上的乘积
83.
84. 输入例子
85. 134
86. 输出例子
87. 431 12
88.
89.
90. 解题思路:删繁就简,直接当字符串读入,处理就简单多了。
91. PS:此处不用纠结于题意,没有特别强调是依照一个数的格式输出,因此能够有前导0
92.
93. */
94. #include<iostream>
95. #include<string.h>
96. using namespace std;
97. int main()
98. {
99. string s;
100. int ans=1;
101. cin>>s;
102. for (int i=s.size()-1;i>=0;i--)
103. {
104. cout<<s[i]; //倒序输出每一位
105. ans=ans*(s[i]-'0'); //ans累乘每一位的值
106. }
107. cout<<' '<<ans<<endl;
108. }
109. 中级题
110. 题目描写叙述
111. 输入10个数字,按各个位上的和从小到大排序,假设同样,则按数字从小到大排序。
112.
113. 输入描写叙述
114. 10个正整数。保证都在int范围内。用空格隔开
115. 输出描写叙述
116. 10个数字。其从大到小的值,用空格隔开,最后一个数字后不加空格
117.
118. 输入例子
119. 11 3 2 4 5 9 8 7 10 6
120. 输出例子
121. 10 2 11 3 4 5 6 7 8 9
122.
123. 解题思路:调用C++自带的sort函数,又一次改写compare函数就可以。
124. */
125. #include<iostream>
126. #include<string.h>
127. #include<algorithm> //这个是调用sort函数必须的头文件
128. using namespace std;
129. int arr[10];
130. int cal(int x) //计算一个数字各个位上的和
131. {
132. int ans=0;
133. while (x!=0)
134. {
135. ans+=x%10;
136. x/=10;
137. }
138. return ans;1
139. }
140. int cmp(int i,int j)
141. {
142. if (cal(i)!=cal(j)) //假设两个数字各个位上的和不同样,则依照各个位上的和来排序
143. {
144. return cal(i)<cal(j);
145. }
146. else //否则,即两个数各个位上的和相等。则依照数字本身来排序
147. {
148. return i<j;
149. }
150. }
151. int main()
152. {
153. for (int i=0;i<=9;i++) cin>>arr[i];
154. sort(arr,arr+10,cmp);
155. for (int i=0;i<=9;i++)
156. {
157. cout<<arr[i];
158. if (i!=9) cout<<' '; //假设不是最后一个数字,则须要在两个数字中间输出一个空格。
159. }
160. cout<<endl;
161. //PS:最后一个输出的后面一定要跟回车符而不是空格符
162. }
163. 中级题
164. 题目描写叙述
165. 你有一个容量为100的箩筐。给你30个物品,每一个物品的体积已知问:最多能装多少个物品进箩筐
166. 输入描写叙述
167. 一行30个正整数。用空格隔开,表示每一个物品的体积
168. 输出描写叙述
169. 一个数字,为最多能装下的物品数
170.
171. 输入例子(此处用3个物品作为例子,实际读入为30个)
172. 5 59 100
173. 输出例子
174. 2
175.
176. 解题思路:利用性价比对全部物品进行排序。优先装性价比高的,在此题中。性价比就是物品的体积
177. */
178. #include<iostream>
179. #include<string.h>
180. #include<algorithm> //这个是调用sort函数必须的头文件
181. using namespace std;
182. int arr[31];
183. int main()
184. {
185. for (int i=0;i<=29;i++) cin>>arr[i];
186. sort(arr,arr+30); //从小到大排序
187. //从最小的開始装框。直到装满了为止。
188. int sum=0;
189. for (int i=0;i<=29;i++)
190. {
191. if (sum+arr[i]>100) break; //假设不能装了就立马停下来
192. sum=sum+arr[i]; //否则就把这个也装进去
193. }
194. //程序跳出的那个位置的i,就是我们一共装了的数量,假设所有都装了,则i=30
195. cout<<i<<endl;
196. }
197. 0基础题:(此题是我以前做的机试题)
198. 描写叙述:10个学生考完期末考试评卷完毕后,A老师须要划出及格线。要求例如以下:
199. (1) 及格线是10的倍数;
200. (2) 保证至少有60%的学生及格;
201. (3) 假设全部的学生都高于60分,则及格线为60分
202. (4) 及格线越高越好,但最高不能超过60
203. 输入:输入10个整数,取值0~100
204. 输出:输出及格线,10的倍数
205. 输入例子:61 51 49 30 20 10 70 80 90 99
206. 输出例子:50
207.
208. 解题思路:从高到低枚举及格线。输出第一个满足要求的及格线就是答案
209. */
210. #include<iostream>
211. using namespace std;
212. int arr[10];
213. int main()
214. {
215. for (int i=0;i<=9;i++) cin>>arr[i];
216. int line;
217. for (line=60;line>=0;line-=10) //从高到低枚举分数线
218. {
219. int num=0; //该变量用来统计这个分数线下,是否超过60%同学及格
220. for (int i=0;i<=9;i++)
221. if (arr[i]>=line) //假设分数大于等于及格线,说明在这个分数线下是及格的
222. num++;
223. if (num>=6) //假设超过60%的人及格,在这里10的60%就是6
224. break; //满足了要求就立马break,说明这是分数线
225. }
226. cout<<line<<endl;
227. }
228. 中级题:100分 (此题是我以前做的机试题)
229. 描写叙述:一条长廊里依次装有n(1 ≤ n ≤ 65535)盏电灯,从头到尾编号1、2、3、…n-1、n。
230. 有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下。接着第二个学生把号码凡是2的倍数的电灯的开关拉一下;接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。
231.
232. 输入:电灯的数量
233. 输出:亮着的电灯数量
234. 例子输入:3
235. 例子输出:1
236.
237. 解题思路1:这道题。假设要模拟的话,当然是能够的。但对于代码基础较差的同学写起来就比較吃力了,在这里写模拟的做法
238. 解题思路2:在这道题上面多思考思考,能够看出,对于不论什么一个灯来说。比方12,其因数有1,2,3,4,6,12。说明。编号为1,2,3,4,6,12的学生分别要拉它一下,在这里发现,1*12=12,2*6=12,3*4=12。所以其因数都是一一相应的,也就是,1拉的那一下被12抵消了,2拉的那一下被6抵消了,那么谁不会被抵消呢?答案是平方数。比方9的因数是1,3,9,那么3*3=9,而3仅仅拉一次,所以不会被抵消。
239. 从这道题能够看出,编程的非常多时候,多思考比多动笔要实用的多。
240.
241. */
242. #include<iostream>
243. #include<string.h>
244. using namespace std;
245. int vis[65536],n;
246. int main()
247. {
248. cin>>n;
249. memset(vis,0,sizeof(vis)); //这句话的意思是把vis数组清0,0表示此刻灯是关着的。1表示是开着的
250. for (int i=1;i<=n;i++) //枚举每个学生的编号
251. for (int j=i;j<=n;j+=i) //从j=i開始,每次给j+i。使得i,i*2,i*3,...,这些灯所有都被拉一次开关
252. vis[j]=1-vis[j]; //1->0,0->1。本质上都是用1减去它本身。
253. int ans=0; //统计答案
254. for (int i=1;i<=n;i++)
255. if (vis[i]==1) //假设如今是开灯状态,答案加一
256. ans++;
257. cout<<ans<<endl;
}
上面的全部代码可以看懂。而且自己实现一遍。再练上几个类似的题,过机试肯定没问题,可以轻松写出上面的代码,那么机试优秀肯定没问题。想拿满分,请去学习搜索(dfs,bfs),树(先中后序遍历。及已知遍历对树的构造等)。栈(怎么用数组模拟栈,栈的特性等),图论(最短路算法,连通性推断等),动态规划(这个就太多了。入门请看背包九讲)等等等等。尽管写了这么多。但高级题事实上并没有这么难。高级题主要考搜索比較多一些。偶尔会有树、栈、图、动态规划的题目,只是,要想当个好码农。算法和数据结构基础是必须的
机试葵花宝典就写到这里了。大师兄在大华为等你们哪。来了我们一起在练独孤九剑。六脉神剑。
附好网上还有一师兄机试心得,共小弟妹们參考:
华为机试成功归来,与小伙伴们分享下经验
前段时间參加华为机试,机试通过的能够优先录取,优先选择岗位和工作地,关键是面的好,还能够谈更高的工资。最多在西安能够拿到18W。优点还是蛮多的,抱着试试看的态度就去了。哈哈,华为机试记录正是開始。
提前在网上交了简历,周围同学仅仅要报了软件研发类的相关岗位都收到短信通知,须要用到编程的同学基本上都受到短信了。
考试内容:数组、链表、指针、字符串、循环、枚举、排序等(从考过的同学那儿总结的可能不全)
试题结构:考试总共三道题,说是难中易,0基础题(60分)、中级题(100分)、高级题(160分),最难的接近一百行,说多不多,但自己敲出来还是费了点劲,
考试时间:两个小时。平时练得少可能略微捉鸡点。
最简单的一个
描写叙述:10个学生考完期末考试评卷完毕后,A老师须要划出及格线,要求例如以下:
(1) 及格线是10的倍数;
(2) 保证至少有60%的学生及格;
(3) 假设全部的学生都高于60分,则及格线为60分
输入:输入10个整数。取值0~100
输出:输出及格线。10的倍数
输入例子:61 51 49 30 20 10 70 80 90 99
输出例子:50
自己编写代码简单例如以下:
1. #include <stdio.h>
2.
3.
4. void bubbleSort(int arr[])
5. {
6. int i = 0;
7. int j = 0;
8. int t = 0;
9.
10. for(i = 0;i < 10; i++)
11. {
12. for(j = 0; j < (9 - i); j++)
13. {
14. if(arr[j + 1] < arr[j])
15. {
16. t = arr[j + 1];
17. arr[j + 1] = arr[j];
18. arr[j] = t;
19. }
20. }
21. }
22. }
23.
24. int getPassLine(int a[])
25. {
26. int i = 0;
27.
28. bubbleSort(a);
29.
30. if (a[0] >= 60)
31. {
32. return 60;
33. }
34. else
35. {
36. return ((a[4] / 10) * 10);
37. }
38.
39. }
40.
41.
42.
43. int main()
44. {
45. int a[10] = {0};
46.
47. scanf("%d %d %d %d %d %d %d %d %d %d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9]);
48.
49. printf("%d", getPassLine(a));
50.
51. return 0;
52. }
描写叙述:一条长廊里依次装有n(1 ≤ n ≤ 65535)盏电灯。从头到尾编号1、2、3、…n-1、n。每盏电灯由一个拉线开关控制。
有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下;接着第二个学生把号码凡是2的倍数的电灯的开关拉一下。接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。注:电灯数和学生数一致。
输入:电灯的数量
输出:亮着的电灯数量
例子输入:3
例子输出:1
答案參考:
1. #include <stdio.h>
2.
3. #define MAX_BULB_NUM 65535
4. /*
5. 功能: n个学生按规定走完后。长廊里电灯有几盏亮着。
6. 原型:
7. int GetLightLampNum(int n);
8.
9. 输入參数:
10. int n: 电灯/学生的数量。
11.
12. 返回值:
13. int: 亮着的电灯数量。
14.
15. */
16.
17. int GetLightLampNum(int n)
18. {
19. char Bulb_Flag[MAX_BULB_NUM] = {0}; //0代表灯灭。1代表灯亮
20. unsigned int i;
21. unsigned int j = 1;
22. unsigned int Count = 0;
23.
24. if ((n < 1)||(n > 65535))
25. {
26. return false;
27. }
28.
29. while ( j <= n)
30. {
31. for (int i = 1; i <= n; i++)
32. {
33. if (0 == (i%j))
34. {
35. Bulb_Flag[i-1] += 1;
36. Bulb_Flag[i-1] = Bulb_Flag[i-1]%2 ; //if操作用来反转满足条件的灯泡状态
37. }
38. }
39. j++;
40. }
41.
42. for (i = 0; i < MAX_BULB_NUM; i++)
43. {
44. if (1 == Bulb_Flag[i])
45. {
46. Count++;
47. }
48. }
49.
50. return Count;
51. }
52.
53. int main(void)
54. {
55. int input;
56. scanf("%d",&input);
57. printf("%d",GetLightLampNum(input));
58. }
高级题样题:地铁换乘
描写叙述:已知2条地铁线路。当中A为环线,B为东西向线路。线路都是双向的。经过的网站名分别例如以下。两条线交叉的换乘点用T1、T2表示。编敲代码,随意输入两个网站名称,输出乘坐地铁最少须要经过的车站数量(含输入的起点和终点,换乘网站仅仅计算一次)。
地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18
地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15
输入:输入两个不同的站名
输出:输出最少经过的站数,含输入的起点和终点,换乘网站仅仅计算一次
输入例子:A1 A3
输出例子:3
答案參考:
1. import java.util.*;
2.
3.
4. public class Main {
5.
6. private static int INVALID_POSITION = 255;
7.
8. class BusLine {
9. String busstop[];
10. String lineName;
11.
12. public BusLine(String line) {
13. String[] stops = line.split(" ");
14. this.busstop = new String[stops.length];
15. for (int i = 0; i < stops.length; i++) {
16. this.busstop[i] = stops[i];
17. lineName = stops[0].substring(0, 1);
18. }
19. }
20.
21. /* get the stop position from the line */
22. int getStopPosition (String point) {
23. for (int i = 0; i < busstop.length; i++) {
24. if (busstop[i].equals(point)) {
25. return i;
26. }
27. }
28. return INVALID_POSITION;
29. }
30.
31. int getDistance(String pointA, String pointB) {
32. int positionA = 0;
33. int positionB = 0;
34. int len = 0;
35.
36. positionA = getStopPosition(pointA);
37. positionB = getStopPosition(pointB);
38.
39. if (positionA != INVALID_POSITION && positionB != INVALID_POSITION) {
40. len = Math.abs(positionA - positionB) + 1;
41. if (lineName.equals("A") && len > (busstop.length - len + 2)) {
42. len = (busstop.length - len + 2);
43. }
44.
45. return len;
46. }
47.
48. return INVALID_POSITION;
49. }
50.
51. }
52.
53.
54. public int getRide(String pointA, String pointB) {
55. int i = 0;
56. int min = 255;
57. BusLine lineA = new BusLine("A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18");
58. BusLine lineB = new BusLine("B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15");
59.
60. int[] way = {255, 255, 255, 255, 255, 255, 255, 255};
61.
62. way[0] = lineA.getDistance(pointA, pointB);
63. way[1] = lineB.getDistance(pointA, pointB);
64.
65. way[2] = lineA.getDistance(pointA, "T1") + lineB.getDistance(pointB, "T1") - 1;
66. way[3] = lineB.getDistance(pointA, "T1") + lineA.getDistance(pointB, "T1") - 1;
67.
68. way[4] = lineA.getDistance(pointA, "T2") + lineB.getDistance(pointB, "T2") - 1;
69. way[5] = lineB.getDistance(pointA, "T2") + lineA.getDistance(pointB, "T2") - 1;
70.
71. way[6] = lineB.getDistance(pointA, "T1") + lineB.getDistance(pointB, "T2") + lineA.getDistance("T1", "T2") - 2;
72. way[7] = lineB.getDistance(pointA, "T2") + lineB.getDistance(pointB, "T1") + lineA.getDistance("T1", "T2") - 2;
73.
74. for (i = 0; i < 7; i++) {
75. if (min > way[i]) {
76. min = way[i];
77. }
78. }
79.
80. return min;
81. }
82.
83. public static void main(String[] args) {
84. Main m = new Main();
85. Scanner cin = new Scanner(System.in);
86. String inputStr = cin.nextLine();
87. String stops[] = inputStr.split(" ");
88.
89. System.out.println(m.getRide(stops[0], stops[1]));
90. }
91.
92. }
事实上后来发现整个过程下来还是有点紧张的。
宝典1—内功心法
大华为这个大数据时代土豪金海量式的招聘又要開始了!
!!
最近听说大华为的校招机试立即就要開始了,因为华为软件岗位的招聘仅仅有技术面跟机试是与技术有关的内容,所以机试的地位非常重要。对于机试,除了长期积累的软件基本功以外,还有非常多能够短期训练的东西,类似于考试之前的袭击。能够迅速提高机试成绩,就像在我西电大杨老师考前最后一堂课一定要去。那个重点就是考点阿。
这篇机试葵花宝典的内容是针对华为软件类上机准备的。假设你认真看了本宝典,假设你是真正通过自己能力考上西电的话,想只是都难。
相同想拿高级题的同学,请移步acm.xidian.edu.cn/land/或者poj.org。刷上200道题,机试不想拿满分都难。
对于机试,首先应该调整好自己的心态,不要认为敲代码非常难。机试题非常难,也不要去考虑。万一机试考到自己不会的内容怎么办。要相信,机试题永远是考察每一个人的基础。基础是不会考的非常偏的,会有人恰好做过某个题而做出来那个题,但不会有人恰好没做过一个题而做不出来那个题。
机试之前,应该做的准备有:
1、 买一本《算法竞赛入门经典》,这本书不同于普通的算法或者编程语言的书籍。这本书既讲语言,又讲算法。由浅入深。讲的非常好,能看完前几章而且把例题都做会。想通过机试就非常easy了
2、 调整好心态。时刻告诉自己,哪些小错误是自己曾经常常犯的。最好用笔记本记录下来,写每道题前再看一遍。假设遇到代码调不出来了,先想想自己是否犯过曾经那些错误。还有就是,看了题目以后。先细致想清楚细节,在纸上写清楚自己须要用到的变量,以及代码的基本框架,不要急于动手去写代码
3、 不要惧怕不论什么一道看起来非常难的题目,有不会的就去问身边会的人,让别人给自己讲清楚
4、 心中默念10遍C++跟C除了多了两个加号事实上没有差别,会C就能上手C++
5、 大量的练习是必要且有效的
6、 看完这篇宝典,预过机试、必练此功。
在这里推荐一个帖子,是机试归来的学长写的,写的非常不错,里面的例题在后面的攻略中也会提及, 就在好网上。
宝典二:经常使用招式
1:机试经常使用变量类型
CC++经常使用的变量类型有非常多种,想通过机试,掌握好当中的几种就能够,他们各自是int。double, string, char[]
int 类型是最经常使用的整数类型,对于输入类型是整形的变量,使用int来进行定义和读入。另一种更大的整形变量是long long。在机试中一般不会涉及到考察,假设考虑到运算的过程中有可能超过int的大小。再考虑使用long long。int最大能够到达2^31级别,long long最大能够到达2^63。
PS:有时机试读入多个整数的时候会是这种形式
5,10
中间有一个逗号,在这样的情况下。事实上读入也是非常easy的,能够这么写:
scanf(“%d%c%d”,&a,&b,&c);
或者是:
scanf(“%d”,&a);
getchar();
scanf(“%d”,&c);
有的机试题会说:两个整数之间有若干个空格符或tab字符。在这样的情况下,读入的方式还是使用scanf(“%d%d”,&a,&b)这样,scanf函数或者cin函数都能够非常好的吃掉除了数字字符以外的字符。
double类型是最经常使用的浮点数类型,当运算涉及到小数运算的时候。须要使用double来定义。当中。特别须要注意的一点是。假设使用了例如以下语句:
double x=a/b;
在这里。a和b是int。那么x的值将是a和b整除后的结果,而不是想要的结果,想要得到期望的结果,须改成
double x=(a+0.0)/b;
在这里。将a加上一个浮点数,程序会在后台将它强制转换成一个double类型的数字。此时再除一个整数,就没有问题了
string类型是遇到字符串类问题应该首选的变量,差别于字符数组char[]。string类型是直接将字符数组封装了进去,定义string s相当于定义了一个大小特别长的字符数组。使用string的优点是,避免了使用char数组时定义数组长度过小导致越界,同一时候更加直观的将字符串看做了一个对象。
假设要定义一个string变量,首先得包括string的头文件以及使用C++中的标准命名空间,标准命名空间这个东西,仅仅要记得写上即可,没有不论什么影响。
#include<iostream> //这一句是c++的头文件,c语言代码一样能够把它包括进来,仅仅要将程序后缀名改成.cpp就可以。其它都是一样的。
#include<string.h>
using namespace std;
在不同的环境下。可能会有不同的头文件包括了string的使用方法,可能的头文件有cstring,string。在机试的环境中,一般使用string.h就可以。
定义一个string和定义其它变量方式同样:
string s;
读入和输出string也仅仅须要使用
cin>>s;
cout<<s;
这是比c语言的字符数组要简单了非常多的。
须要注意的是,string类型读入的时候与char数组的scanf读入一样,都是遇到空格符或者回车符就停止读入,当做一个完整字符串来处理,因此。使用string处理带空格的字符串是不明智的,其它情况下是都能够的。
string变量包括了非常多强大的功能,如:
[cpp] view plaincopyprint?
1. s[i]; //这么写。返回的就是字符串s第i+1位的字符,返回的类型是char型,当中,s[0]是它的第一位,与字符串同样。
2. s.size(); //返回字符串的长度,返回的长度是l,则s从s[0]到s[l-1]表示的是其每一位的字符。
3. if (s1<s2) //两个string是能够方便的使用大小于符号以及等于号来比較大小的。比較的方式是,从左向右按位进行比較。每一位依照字典序来比較。如”aaaa”<”abc”<”bcd”,但值得注意的一点是。比較的时候应用变量进行比較,即s1<s2这样的,而不能用”aa”<”bb”这样。假设要比較他俩的大小,应这么写:
4. s1="aa"; s2="bb";
5. if (s1<s2)
string类型还有非常多强大的功能,可是对于机试来说,会使用以上三种功能就足够了。
char[50],char[100]这样的字符数组与string类型非常像,仅仅只是他是C语言里面的使用方法。对于机试,仅仅建议在输入带有空格字符的字符串时使用char数组。使用的方式是:
gets(s);
在这里。gets函数差别于scanf函数的是,gets函数会直接将一整行读进来,而不会遇到空格就停下来。
常见机试题类型
0基础题常见的类型无非就是字符串处理类的题目和数字处理类的题目。在这里归结例如以下:
1:字符串处理类
字符串全部大写转小写:
1. for (int i=0;i<s.size();i++)
2. if (s[i]>=’A’ && s[i]<=’Z’)
3. s[i]=s[i]-’A’+’a’;
//s[i]-’A’返回的是两个大写字母之间的差值,比方’C’与’A’的差值是2,这个差值是一个int类型,也能够直接提取出来使用。给这个差值再加上字母’a’。相当于给’a’再往后推移二位,变成字母’c’。这样的使用方法是字符串内最普遍的一种使用方法。小写转大写也是一样。
删除满足指定要求的字符后输出:
在机试中,判定对错的方式是比較输出的结果。而非检查内部的结果。因此,“删除”对于机试来说,相当于“不输出”,也就是说。不须要调用s.erase()函数,仅仅须要在遇到被删除的字符时。跳过,不输出就可以。
1. for (int i=0;i<s.size();i++)
2. {
3. if (s[i]满足删除要求) 跳过;
4. else 输出s[i];
5. }
倒转字符串:
与删除字符串的思路类似,倒转一个字符串,事实上就是倒着输出,仅仅须要将循环反过来就能够。
1. for (int i=s.size()-1;i>=0;i--)
字符串比較大小:
假设比較的规则与字符串的比較规则同样。则直接使用s1>s2这样的方式,假设规则不同,则用一重循环按位比較就可以。
2、数字处理类
数字处理类的题目,最常见的两种考察形式是整数拆分、进制转换和排序。
整数拆分是指将一个整数拆分开每一位。比方123拆分成1,2,3。整数拆分的思路有两种,第一种是直接用字符串读入。然后把每一位用字符的形式提取出来:
[cpp] view plaincopyprint?
1. for (int i=0;i<s.size();i++)
2. <span style="white-space:pre"> </span>num[i]=s[i]-'0';
另一种思路是不断去除以10。把余数提取出来。方法是:
[cpp] view plaincopyprint?
1. while (n!=0)
2. {
3. <span style="white-space:pre"> </span>num[i]=n%10;
4. <span style="white-space:pre"> </span>n=n/10;
5. <span style="white-space:pre"> </span>i++;
6. }
进制转换:
进制转换又分为10进制转换成别的进制以及别的进制转换成10进制,进制转换事实上特别简单。仅仅须要记住例如以下代码:
10进制转换成X进制
[cpp] view plaincopyprint?
1. while (n!=0)
2. {
3. <span style="white-space:pre"> </span>num[i]=n%x;
4. <span style="white-space:pre"> </span>i++;
5. <span style="white-space:pre"> </span>n=n/x;
6. }
X进制转换成10进制
[cpp] view plaincopyprint?
1. for (int i=0;i<=length;i++)
2. {
3. ans=ans*x+num[i];
4. }
当中,num[i]表示的是该x进制数的每一位,比方一个二进制数101。用这样的转换方式去转换。ans的值从i=0到i=2处理后各自是1,2,5。
排序:
排序这个东西。事实上不须要学习冒泡啊、快排啊之类的算法,应对机试,C++中自带的sort函数就能够非常好的解决,请看以下一段代码
[cpp] view plaincopyprint?
1. </pre><pre name="code" class="cpp">#include<iostream>
2. #include<algorithm> //这个是包括sort函数的头文件
3. using namespace std;
4. int arr[100],n;
5. int cmp(int x,int y) //这个函数是sort函数比較两个元素优先级的函数。在这里计算出两个元素的优先级,然后返回就可以。
6. {
7. int importance1,importance2;
8. //此处插入代码计算x,y的重要性
9. return importance1<importance2; //此处返回小于号。意思是优先级小的在前。如return x<y;则数组会由小到大排序
10. }
11. int main()
12. {
13. cin>>n;
14. for (int i=0;i<n;i++) cin>>arr[i];
15. sort(arr,arr+n,cmp);
16. return 0;
17. }
这一段代码的作用是读入n个数字,然后按优先级进行排序,排序的比較方法在cmp函数中实现,排序的详细过程不须要考虑。
能够看到。事实上仅仅须要记住sort函数的使用方法,要通过机试,排序算法是根本不须要学习的,so easy!
总结:机试中。掌握好int。double,string。char[],还有数组,就足够用了,但考察的内容不不过上述这些,想要通过机试,还是应该多多练习,多多学习,不局限于上面所说的内容
宝典三:擂台实战
首先推荐一个站点:acm.xidian.edu.cn/land/,上面的非常多题目,难度非常适合机试,如:
非常easy:1031,1120,1122,1121,1103,1104,1281,
简单:1049,1181,1182,1279,1280。
中等:1106,1108,1183,1288.
难:1105,1282,1283,
大家能够依据自己的水平去训练,事实上里面的难题也是非常easy的,归类到题库中的话都属于简单题,仅仅要好好看书学习都是能够做出来的,以下放几道例题,这些题都是机试非常有可能考的题目,或者是非常类似的题目。已经有了细致的凝视,代码写的仓促
1. 简单题
2. 题目描写叙述
3. 输入一个字符串,删除当中全部的数字,全部大写字母改成小写,其它不变。并输出
4.
5. 输入描写叙述
6. 一个字符串,保证没有空格。以回车符结束。字符串长度<=20
7. 输出描写叙述
8. 一个字符串。为题目要求的结果
9.
10. 输入例子
11. aAbB13A
12. 输出例子
13. aabba
14.
15. 解题思路:模拟题目要求就可以,遇到数字就跳过不输出,遇到大写字母就改成小写。
16.
17. */
18. #include<iostream>
19. #include<string.h>
20. using namespace std;
21. int main()
22. {
23. string s;
24. cin>>s;
25. for (int i=0;i<s.size();i++) //枚举字符串的每一位
26. {
27. if (s[i]>='0' && s[i]<='9') continue; //遇到数字就跳过
28. if (s[i]>='A' && s[i]<='Z') s[i]=s[i]-'A'+'a'; //遇到大写字母就改成小写
29. cout<<s[i];
30. }
31. cout<<endl;
32. }
33. </span>
34. 简单题
35. 题目描写叙述
36. 输入一个字符串,统计其出现频率最高的字符,并输出。若存在两个字符出现频率同样,则输出字典序较小的那一个
37.
38. 输入描写叙述
39. 一个字符串,保证没有空格,以回车符结束,字符串长度<=20
40. 输出描写叙述
41. 一个字符
42.
43. 输入例子
44. aabbaabb
45. 输出例子
46. a
47.
48. 解题思路:做一个频率数组来统计全部字符的出现频率,机试时候不会有汉字输入。因此仅仅考虑输入是ASCII编码的情况。
49.
50. */
51. #include<iostream>
52. #include<string.h>
53. using namespace std;
54. int f[200]; //频率数组
55. int biggest=0; //记录最大的值
56. int main()
57. {
58. memset(f,0,sizeof(f)); //将f中的所有元素变成0,写循环也可
59. string s;
60. cin>>s;
61. for (int i=0;i<s.size();i++) //枚举字符串的每一位
62. {
63. int num=s[i]; //将s[i]转换成它的ascii码
64. f[num]++; //频率次数加1
65. biggest=max(biggest,f[s[i]]); //比較找出最大的
66. }
67. for (int i=0;i<=129;i++) //枚举全部的字符的频率,找出频率最高且字典序最小的那一个
68. if (f[i]==biggest) //假设满足要求
69. {
70. cout<<(char)(i)<<endl;
71. break; //这句break保证了我们仅仅会输出一个满足要求的结果
72. }
73. }
74. /*
75. 简单题
76. 题目描写叙述
77. 输入一个数字,将其倒序输出。并输出其各个位上的乘积
78.
79. 输入描写叙述
80. 一个正整数,保证在int范围内
81. 输出描写叙述
82. 两个数字,用空格隔开。第一个数字为其倒序的值,第二个数字是各个位上的乘积
83.
84. 输入例子
85. 134
86. 输出例子
87. 431 12
88.
89.
90. 解题思路:删繁就简,直接当字符串读入,处理就简单多了。
91. PS:此处不用纠结于题意,没有特别强调是依照一个数的格式输出,因此能够有前导0
92.
93. */
94. #include<iostream>
95. #include<string.h>
96. using namespace std;
97. int main()
98. {
99. string s;
100. int ans=1;
101. cin>>s;
102. for (int i=s.size()-1;i>=0;i--)
103. {
104. cout<<s[i]; //倒序输出每一位
105. ans=ans*(s[i]-'0'); //ans累乘每一位的值
106. }
107. cout<<' '<<ans<<endl;
108. }
109. 中级题
110. 题目描写叙述
111. 输入10个数字,按各个位上的和从小到大排序,假设同样,则按数字从小到大排序。
112.
113. 输入描写叙述
114. 10个正整数。保证都在int范围内。用空格隔开
115. 输出描写叙述
116. 10个数字。其从大到小的值,用空格隔开,最后一个数字后不加空格
117.
118. 输入例子
119. 11 3 2 4 5 9 8 7 10 6
120. 输出例子
121. 10 2 11 3 4 5 6 7 8 9
122.
123. 解题思路:调用C++自带的sort函数,又一次改写compare函数就可以。
124. */
125. #include<iostream>
126. #include<string.h>
127. #include<algorithm> //这个是调用sort函数必须的头文件
128. using namespace std;
129. int arr[10];
130. int cal(int x) //计算一个数字各个位上的和
131. {
132. int ans=0;
133. while (x!=0)
134. {
135. ans+=x%10;
136. x/=10;
137. }
138. return ans;1
139. }
140. int cmp(int i,int j)
141. {
142. if (cal(i)!=cal(j)) //假设两个数字各个位上的和不同样,则依照各个位上的和来排序
143. {
144. return cal(i)<cal(j);
145. }
146. else //否则,即两个数各个位上的和相等。则依照数字本身来排序
147. {
148. return i<j;
149. }
150. }
151. int main()
152. {
153. for (int i=0;i<=9;i++) cin>>arr[i];
154. sort(arr,arr+10,cmp);
155. for (int i=0;i<=9;i++)
156. {
157. cout<<arr[i];
158. if (i!=9) cout<<' '; //假设不是最后一个数字,则须要在两个数字中间输出一个空格。
159. }
160. cout<<endl;
161. //PS:最后一个输出的后面一定要跟回车符而不是空格符
162. }
163. 中级题
164. 题目描写叙述
165. 你有一个容量为100的箩筐。给你30个物品,每一个物品的体积已知问:最多能装多少个物品进箩筐
166. 输入描写叙述
167. 一行30个正整数。用空格隔开,表示每一个物品的体积
168. 输出描写叙述
169. 一个数字,为最多能装下的物品数
170.
171. 输入例子(此处用3个物品作为例子,实际读入为30个)
172. 5 59 100
173. 输出例子
174. 2
175.
176. 解题思路:利用性价比对全部物品进行排序。优先装性价比高的,在此题中。性价比就是物品的体积
177. */
178. #include<iostream>
179. #include<string.h>
180. #include<algorithm> //这个是调用sort函数必须的头文件
181. using namespace std;
182. int arr[31];
183. int main()
184. {
185. for (int i=0;i<=29;i++) cin>>arr[i];
186. sort(arr,arr+30); //从小到大排序
187. //从最小的開始装框。直到装满了为止。
188. int sum=0;
189. for (int i=0;i<=29;i++)
190. {
191. if (sum+arr[i]>100) break; //假设不能装了就立马停下来
192. sum=sum+arr[i]; //否则就把这个也装进去
193. }
194. //程序跳出的那个位置的i,就是我们一共装了的数量,假设所有都装了,则i=30
195. cout<<i<<endl;
196. }
197. 0基础题:(此题是我以前做的机试题)
198. 描写叙述:10个学生考完期末考试评卷完毕后,A老师须要划出及格线。要求例如以下:
199. (1) 及格线是10的倍数;
200. (2) 保证至少有60%的学生及格;
201. (3) 假设全部的学生都高于60分,则及格线为60分
202. (4) 及格线越高越好,但最高不能超过60
203. 输入:输入10个整数,取值0~100
204. 输出:输出及格线,10的倍数
205. 输入例子:61 51 49 30 20 10 70 80 90 99
206. 输出例子:50
207.
208. 解题思路:从高到低枚举及格线。输出第一个满足要求的及格线就是答案
209. */
210. #include<iostream>
211. using namespace std;
212. int arr[10];
213. int main()
214. {
215. for (int i=0;i<=9;i++) cin>>arr[i];
216. int line;
217. for (line=60;line>=0;line-=10) //从高到低枚举分数线
218. {
219. int num=0; //该变量用来统计这个分数线下,是否超过60%同学及格
220. for (int i=0;i<=9;i++)
221. if (arr[i]>=line) //假设分数大于等于及格线,说明在这个分数线下是及格的
222. num++;
223. if (num>=6) //假设超过60%的人及格,在这里10的60%就是6
224. break; //满足了要求就立马break,说明这是分数线
225. }
226. cout<<line<<endl;
227. }
228. 中级题:100分 (此题是我以前做的机试题)
229. 描写叙述:一条长廊里依次装有n(1 ≤ n ≤ 65535)盏电灯,从头到尾编号1、2、3、…n-1、n。
每盏电灯由一个拉线开关控制。
開始,电灯所有关着。
230. 有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下。接着第二个学生把号码凡是2的倍数的电灯的开关拉一下;接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。
注:电灯数和学生数一致。
231.
232. 输入:电灯的数量
233. 输出:亮着的电灯数量
234. 例子输入:3
235. 例子输出:1
236.
237. 解题思路1:这道题。假设要模拟的话,当然是能够的。但对于代码基础较差的同学写起来就比較吃力了,在这里写模拟的做法
238. 解题思路2:在这道题上面多思考思考,能够看出,对于不论什么一个灯来说。比方12,其因数有1,2,3,4,6,12。说明。编号为1,2,3,4,6,12的学生分别要拉它一下,在这里发现,1*12=12,2*6=12,3*4=12。所以其因数都是一一相应的,也就是,1拉的那一下被12抵消了,2拉的那一下被6抵消了,那么谁不会被抵消呢?答案是平方数。比方9的因数是1,3,9,那么3*3=9,而3仅仅拉一次,所以不会被抵消。
因此。这道题的答案就是。输入的n以内的平方数个数,等于(int)sqrt(n)。
239. 从这道题能够看出,编程的非常多时候,多思考比多动笔要实用的多。
240.
241. */
242. #include<iostream>
243. #include<string.h>
244. using namespace std;
245. int vis[65536],n;
246. int main()
247. {
248. cin>>n;
249. memset(vis,0,sizeof(vis)); //这句话的意思是把vis数组清0,0表示此刻灯是关着的。1表示是开着的
250. for (int i=1;i<=n;i++) //枚举每个学生的编号
251. for (int j=i;j<=n;j+=i) //从j=i開始,每次给j+i。使得i,i*2,i*3,...,这些灯所有都被拉一次开关
252. vis[j]=1-vis[j]; //1->0,0->1。本质上都是用1减去它本身。
253. int ans=0; //统计答案
254. for (int i=1;i<=n;i++)
255. if (vis[i]==1) //假设如今是开灯状态,答案加一
256. ans++;
257. cout<<ans<<endl;
}
上面的全部代码可以看懂。而且自己实现一遍。再练上几个类似的题,过机试肯定没问题,可以轻松写出上面的代码,那么机试优秀肯定没问题。想拿满分,请去学习搜索(dfs,bfs),树(先中后序遍历。及已知遍历对树的构造等)。栈(怎么用数组模拟栈,栈的特性等),图论(最短路算法,连通性推断等),动态规划(这个就太多了。入门请看背包九讲)等等等等。尽管写了这么多。但高级题事实上并没有这么难。高级题主要考搜索比較多一些。偶尔会有树、栈、图、动态规划的题目,只是,要想当个好码农。算法和数据结构基础是必须的
机试葵花宝典就写到这里了。大师兄在大华为等你们哪。来了我们一起在练独孤九剑。六脉神剑。
附好网上还有一师兄机试心得,共小弟妹们參考:
华为机试成功归来,与小伙伴们分享下经验
前段时间參加华为机试,机试通过的能够优先录取,优先选择岗位和工作地,关键是面的好,还能够谈更高的工资。最多在西安能够拿到18W。优点还是蛮多的,抱着试试看的态度就去了。哈哈,华为机试记录正是開始。
提前在网上交了简历,周围同学仅仅要报了软件研发类的相关岗位都收到短信通知,须要用到编程的同学基本上都受到短信了。
一天三波。在西工大毅字楼三楼机房。南门进去直走左拐就到了。我是第二天早上的机试,前一天已经听机试过的同学考的内容涉及数组、链表、指针、字符串、循环、枚举、排序等吧,这个预计要看人品,平时出门多扶老奶奶过马路吧。事实上考过后发现这个机试跟平时做项目不一样,项目可能很多其它的注重实现研究所须要的某个功能不会去注意这么多细节,可是机试考的很多其它的是基本功。
以下重点跟大家分享下上机题吧,我仅仅列举了我抽到的三个。其它同学抽到的跟这个大同小异吧。
大家自己编写下,对即将開始的面试都会有帮助的。
考试内容:数组、链表、指针、字符串、循环、枚举、排序等(从考过的同学那儿总结的可能不全)
试题结构:考试总共三道题,说是难中易,0基础题(60分)、中级题(100分)、高级题(160分),最难的接近一百行,说多不多,但自己敲出来还是费了点劲,
考试时间:两个小时。平时练得少可能略微捉鸡点。
最简单的一个
描写叙述:10个学生考完期末考试评卷完毕后,A老师须要划出及格线,要求例如以下:
(1) 及格线是10的倍数;
(2) 保证至少有60%的学生及格;
(3) 假设全部的学生都高于60分,则及格线为60分
输入:输入10个整数。取值0~100
输出:输出及格线。10的倍数
输入例子:61 51 49 30 20 10 70 80 90 99
输出例子:50
自己编写代码简单例如以下:
1. #include <stdio.h>
2.
3.
4. void bubbleSort(int arr[])
5. {
6. int i = 0;
7. int j = 0;
8. int t = 0;
9.
10. for(i = 0;i < 10; i++)
11. {
12. for(j = 0; j < (9 - i); j++)
13. {
14. if(arr[j + 1] < arr[j])
15. {
16. t = arr[j + 1];
17. arr[j + 1] = arr[j];
18. arr[j] = t;
19. }
20. }
21. }
22. }
23.
24. int getPassLine(int a[])
25. {
26. int i = 0;
27.
28. bubbleSort(a);
29.
30. if (a[0] >= 60)
31. {
32. return 60;
33. }
34. else
35. {
36. return ((a[4] / 10) * 10);
37. }
38.
39. }
40.
41.
42.
43. int main()
44. {
45. int a[10] = {0};
46.
47. scanf("%d %d %d %d %d %d %d %d %d %d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9]);
48.
49. printf("%d", getPassLine(a));
50.
51. return 0;
52. }
描写叙述:一条长廊里依次装有n(1 ≤ n ≤ 65535)盏电灯。从头到尾编号1、2、3、…n-1、n。每盏电灯由一个拉线开关控制。
開始。电灯所有关着。
有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下;接着第二个学生把号码凡是2的倍数的电灯的开关拉一下。接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。注:电灯数和学生数一致。
输入:电灯的数量
输出:亮着的电灯数量
例子输入:3
例子输出:1
答案參考:
1. #include <stdio.h>
2.
3. #define MAX_BULB_NUM 65535
4. /*
5. 功能: n个学生按规定走完后。长廊里电灯有几盏亮着。
6. 原型:
7. int GetLightLampNum(int n);
8.
9. 输入參数:
10. int n: 电灯/学生的数量。
11.
12. 返回值:
13. int: 亮着的电灯数量。
14.
15. */
16.
17. int GetLightLampNum(int n)
18. {
19. char Bulb_Flag[MAX_BULB_NUM] = {0}; //0代表灯灭。1代表灯亮
20. unsigned int i;
21. unsigned int j = 1;
22. unsigned int Count = 0;
23.
24. if ((n < 1)||(n > 65535))
25. {
26. return false;
27. }
28.
29. while ( j <= n)
30. {
31. for (int i = 1; i <= n; i++)
32. {
33. if (0 == (i%j))
34. {
35. Bulb_Flag[i-1] += 1;
36. Bulb_Flag[i-1] = Bulb_Flag[i-1]%2 ; //if操作用来反转满足条件的灯泡状态
37. }
38. }
39. j++;
40. }
41.
42. for (i = 0; i < MAX_BULB_NUM; i++)
43. {
44. if (1 == Bulb_Flag[i])
45. {
46. Count++;
47. }
48. }
49.
50. return Count;
51. }
52.
53. int main(void)
54. {
55. int input;
56. scanf("%d",&input);
57. printf("%d",GetLightLampNum(input));
58. }
高级题样题:地铁换乘
描写叙述:已知2条地铁线路。当中A为环线,B为东西向线路。线路都是双向的。经过的网站名分别例如以下。两条线交叉的换乘点用T1、T2表示。编敲代码,随意输入两个网站名称,输出乘坐地铁最少须要经过的车站数量(含输入的起点和终点,换乘网站仅仅计算一次)。
地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18
地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15
输入:输入两个不同的站名
输出:输出最少经过的站数,含输入的起点和终点,换乘网站仅仅计算一次
输入例子:A1 A3
输出例子:3
答案參考:
1. import java.util.*;
2.
3.
4. public class Main {
5.
6. private static int INVALID_POSITION = 255;
7.
8. class BusLine {
9. String busstop[];
10. String lineName;
11.
12. public BusLine(String line) {
13. String[] stops = line.split(" ");
14. this.busstop = new String[stops.length];
15. for (int i = 0; i < stops.length; i++) {
16. this.busstop[i] = stops[i];
17. lineName = stops[0].substring(0, 1);
18. }
19. }
20.
21. /* get the stop position from the line */
22. int getStopPosition (String point) {
23. for (int i = 0; i < busstop.length; i++) {
24. if (busstop[i].equals(point)) {
25. return i;
26. }
27. }
28. return INVALID_POSITION;
29. }
30.
31. int getDistance(String pointA, String pointB) {
32. int positionA = 0;
33. int positionB = 0;
34. int len = 0;
35.
36. positionA = getStopPosition(pointA);
37. positionB = getStopPosition(pointB);
38.
39. if (positionA != INVALID_POSITION && positionB != INVALID_POSITION) {
40. len = Math.abs(positionA - positionB) + 1;
41. if (lineName.equals("A") && len > (busstop.length - len + 2)) {
42. len = (busstop.length - len + 2);
43. }
44.
45. return len;
46. }
47.
48. return INVALID_POSITION;
49. }
50.
51. }
52.
53.
54. public int getRide(String pointA, String pointB) {
55. int i = 0;
56. int min = 255;
57. BusLine lineA = new BusLine("A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10 A11 A12 A13 T2 A14 A15 A16 A17 A18");
58. BusLine lineB = new BusLine("B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10 T2 B11 B12 B13 B14 B15");
59.
60. int[] way = {255, 255, 255, 255, 255, 255, 255, 255};
61.
62. way[0] = lineA.getDistance(pointA, pointB);
63. way[1] = lineB.getDistance(pointA, pointB);
64.
65. way[2] = lineA.getDistance(pointA, "T1") + lineB.getDistance(pointB, "T1") - 1;
66. way[3] = lineB.getDistance(pointA, "T1") + lineA.getDistance(pointB, "T1") - 1;
67.
68. way[4] = lineA.getDistance(pointA, "T2") + lineB.getDistance(pointB, "T2") - 1;
69. way[5] = lineB.getDistance(pointA, "T2") + lineA.getDistance(pointB, "T2") - 1;
70.
71. way[6] = lineB.getDistance(pointA, "T1") + lineB.getDistance(pointB, "T2") + lineA.getDistance("T1", "T2") - 2;
72. way[7] = lineB.getDistance(pointA, "T2") + lineB.getDistance(pointB, "T1") + lineA.getDistance("T1", "T2") - 2;
73.
74. for (i = 0; i < 7; i++) {
75. if (min > way[i]) {
76. min = way[i];
77. }
78. }
79.
80. return min;
81. }
82.
83. public static void main(String[] args) {
84. Main m = new Main();
85. Scanner cin = new Scanner(System.in);
86. String inputStr = cin.nextLine();
87. String stops[] = inputStr.split(" ");
88.
89. System.out.println(m.getRide(stops[0], stops[1]));
90. }
91.
92. }
事实上后来发现整个过程下来还是有点紧张的。
数组、链表、指针、字符串、循环、枚举、排序等内容基本上都考察到了。
大家借鉴下吧。
我的难度比其它同学难度大了些,最后一个当时没測试通过。回来才调过。做对了两道。
加油吧,毕业季里相互分享下资料,互惠互利。