百度2017春招笔试真题编程题集合

百度2017春招笔试真题编程题集合

题目来源:https://www.nowcoder.com/test/4998655/summary

1.[编程题] 买帽子

度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同。度度熊想买一顶价格第三便宜的帽子,问第三便宜的帽子价格是多少?

输入描述:

首先输入一个正整数N(N <= 50),接下来输入N个数表示每顶帽子的价格(价格均是正整数,且小于等于1000)

输出描述:

如果存在第三便宜的帽子,请输出这个价格是多少,否则输出-1

输入例子:

10

10 10 10 10 20 20 30 30 40 40

输出例子:

30

分析:直接使用STL中的set插入去重,输入第三小元素即可。

 1 #include<iostream>
 2 #include<set>
 3 using namespace std;
 4 int main()
 5 {
 6     int n, a;
 7     set <int> NUM;
 8     cin >> n;
 9     for (int i = 0; i<n; i++)
10     {
11         cin >> a;
12         NUM.insert(a);
13     }
14     set <int>::iterator it;
15     int m = 0;
16     for (it = NUM.begin(); it != NUM.end(); it++)
17     {
18         m++;
19         if (m == 3)
20             cout << *it << endl;
21     }
22     if (m<3)  cout << "-1" << endl;
23     return 0;
24 }

 

2.[编程题] 度度熊回家

一个数轴上共有N个点,第一个点的坐标是度度熊现在位置,第N-1个点是度度熊的家。现在他需要依次的从0号坐标走到N-1号坐标。

 但是除了0号坐标和N-1号坐标,他可以在其余的N-2个坐标中选出一个点,并直接将这个点忽略掉,问度度熊回家至少走多少距离?

输入描述:

输入一个正整数N, N <= 50。

接下来N个整数表示坐标,正数表示X轴的正方向,负数表示X轴的负方向。绝对值小于等于100

输出描述:

输出一个整数表示度度熊最少需要走的距离。

输入例子:

4

1 4 -1 3

输出例子:

4

分析:先计算未去除中间点的总路程,之后枚举除了两端,去除中间点之后路程减少的值,总路程减去减少的最大值即为所求。

 1 #include<iostream>  
 2 #include<algorithm> 
 3 #include<vector>
 4 #include<cmath>  
 5 using namespace std;
 6 int main()
 7 {
 8     int n; cin >> n;
 9     int result = 0;
10     vector<int>temp(n, 0);
11     cin >> temp[0];
12     for (int i = 1; i < n; ++i)
13     {
14         cin >> temp[i];
15         result += abs(temp[i] - temp[i - 1]);  //在没有去除点时,总路程
16     }
17     int maxx = 0;
18     for (int i = 1; i < temp.size() - 1; ++i)
19     {
20         maxx = max(maxx, abs(temp[i] - temp[i - 1]) + abs(temp[i] - temp[i + 1]) - abs(temp[i + 1] - temp[i - 1]));//计算去掉中间点后  路程减少最多的距离
21     }
22 
23     cout << result - maxx << endl;  //总路程- 减少路程最多的即可
24 }

 

3.[编程题] 寻找三角形

三维空间中有N个点,每个点可能是三种颜色的其中之一,三种颜色分别是红绿蓝,分别用'R', 'G', 'B'表示。

 现在要找出三个点,并组成一个三角形,使得这个三角形的面积最大。

 但是三角形必须满足:三个点的颜色要么全部相同,要么全部不同。

输入描述:

首先输入一个正整数N三维坐标系内的点的个数.(N <= 50)

接下来N行,每一行输入 c x y z,c为'R', 'G', 'B' 的其中一个。x,y,z是该点的坐标。(坐标均是0到999之间的整数)

输出描述:

输出一个数表示最大的三角形面积,保留5位小数。

输入例子:

5

R 0 0 0

R 0 4 0

R 0 0 3

G 92 14 7

G 12 16 8

输出例子:

6.00000

分析:通过海伦公式s=sqrt(p* (p-a) * (p-b) * (p-c)) 其中p=(a+b+c) / 2 ,a、b、c为三角形三边长,暴力计算三角形面积,取出满足条件的最大值

 1 #include<iostream>
 2 #include<cmath>
 3 #include<stdlib.h>
 4 #include <iterator>
 5 using namespace std;
 6 
 7 struct noode
 8 {
 9     char coolor;
10     int x, y, z;
11 };
12 
13 double dis(noode a, noode b)
14 {
15     return sqrt(1.0*(a.x - b.x)*(a.x - b.x) + 1.0*(a.y - b.y)*(a.y - b.y) + 1.0*(a.z - b.z)*(a.z - b.z));
16 }
17 
18 int main()
19 {
20     int n;
21     double mmax = -1e9;
22     cin >> n;
23     noode ai[100];
24     for (int i = 0; i<n; i++)
25     {
26         cin >> ai[i].coolor >> ai[i].x >> ai[i].y >> ai[i].z;
27     }
28     for (int i = 0; i<n; i++)
29     {
30         for (int j = 0; j<n; j++)
31         {
32             if (i == j) 
33                 continue;
34             for (int k = 0; k<n; k++)
35             {
36                 if (k == i || k == j) 
37                     continue;
38                 if ((ai[i].coolor == ai[j].coolor&&ai[j].coolor == ai[k].coolor) || (ai[i].coolor != ai[j].coolor&&ai[j].coolor 
39                     != ai[k].coolor&&ai[i].coolor != ai[k].coolor))
40                 {
41                     double a = dis(ai[i], ai[j]);
42                     double b = dis(ai[i], ai[k]);
43                     double c = dis(ai[j], ai[k]);
44                     double p = (a + b + c) / 2;
45                     double mianji = sqrt(p*(p - a)*(p - b)*(p - c));
46                     if (mianji>mmax) 
47                         mmax = mianji;
48                     //cout<<a<<" "<<b<<" "<<c<<endl;
49                 }
50 
51             }
52         }
53     }
54     printf("%.5lf\n", mmax);
55     return 0;
56 }

 

4.[编程题] 有趣的排序

度度熊有一个N个数的数组,他想将数组从小到大 排好序,但是萌萌的度度熊只会下面这个操作:

 任取数组中的一个数然后将它放置在数组的最后一个位置。

 问最少操作多少次可以使得数组从小到大有序?

输入描述:

首先输入一个正整数N,接下来的一行输入N个整数。(N <= 50, 每个数的绝对值小于等于1000)

输出描述:

输出一个整数表示最少的操作次数。

输入例子:

4

19 7 8 25

输出例子:

2

分析:对原数组进行从小到大排序,存储到一个新数组,在未排序数组中从第一个开始找,找完整个数组,然后找到几个,则几个不用动

 1 #include <iostream>
 2 using namespace std;
 3 #define MAX_NUM 50
 4 int main()
 5 {
 6     int N;
 7     cin >> N;
 8     int num[MAX_NUM];
 9     int sortnum[MAX_NUM];
10     for (int i = 0; i < N; i++)  //键入数组
11     {
12         cin >> num[i];
13         sortnum[i] = num[i];
14     }
15     for (int i = 0; i < N; i++)    //排序
16     {
17         for (int j = i + 1; j < N; j++)
18         {
19             if (sortnum[i]>sortnum[j])
20             {
21                 int temp = sortnum[i];
22                 sortnum[i] = sortnum[j];
23                 sortnum[j] = temp;
24             }
25         }
26     }
27     int count = 0;
28     for (int i = 0; i < N; i++)   //比较
29     {
30         if (num[i] == sortnum[count])
31             count++;
32     }
33     cout << N - count;
34     return 0;
35 }

 

5.[编程题] 不等式数列

度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 '>' 和 '<' )使其成为一个合法的不等式数列。但是现在度度熊手中只有k个小于符号即('<'')和n-k-1个大于符号(即'>'),度度熊想知道对于1至n任意的排列中有多少个排列可以使用这些符号使其为合法的不等式数列。

输入描述:

输入包括一行,包含两个整数n和k(k < n ≤ 1000)

输出描述:

输出满足条件的排列数,答案对2017取模。

输入例子:

5 2

输出例子:

66

分析:这道题牵扯到动态规划,不是特别理解

完全依据牛客网上大神的动态规划思想的解答思路:

dp[i][j]表示有i个数字及j个小于号所能组成的数量(大于号数量当然是i - j - 1次,后面需要使用)
而加入第i + 1个数字时,分以下四种情况:
1.如果将i+1插入当前序列的开头,即有了1<2,加入后成为3>1<2,会发现等于同时加入了一个大于号!(此时可以无视1与2之间的关系,因为i+1>i)
2.如果将i+1插入当前序列末尾,即1<2变成了 1<2<3,会发现等于同时加入了一个小于号! (此时可以无视1与2之间的关系,因为i+1>i)
3.如果将i+1加入一个小于号之间,即已经有 1<2了,向中间加入3,会发现变成了1<3>2,等于同时加入了一个大于号!
4.如果将i+1加入一个大于号中间,即有了2>1,变成了2<3>1,等于同时加入了一个小于号!
综上所述,dp[i][j]等于以上四种情况之和:
dp[i - 1][j]                                     //将i加在开头等于加入一个大于号,即要求i-1个数时已经有了j个小于号
dp[i - 1][j - 1]                               //将i加在末尾等于加入一个小于号,即要求i-1个数时已经有了j-1个小于号
dp[i - 1][j] * j                                //将i加在任意一个小于号之间,等于加入了一个大于号;即要求i-1个数时已经有了j个小于号,每个小于                                                         号都可以进行这样的一次插入
dp[i - 1][j - 1] * (i- j - 1)              //将i加载任意一个大于号之间,等于加入了一个小于号;即要求i-1个数时有了j-1个小于号,而此时共有
                                                        (i - 1) - (j - 1)- 1个大于号,每个大于号都要进行一次这样的操作
 
合并同类项即为:
 dp[i][j] = (dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1))
 
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int n, k, ans;
 6 int dp[1005][1005];
 7 int main() {
 8     cin >> n >> k;
 9     for (int i = 1; i <= n; i++)
10         dp[i][0] = 1;
11     for (int i = 2; i <= n; i++)
12         for (int j = 1; j <= k; j++)
13             dp[i][j] = (dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1)) % 2017;
14     cout << dp[n][k] % 2017 << endl;
15     return 0;
16 }

 

posted @ 2017-06-03 10:04  walanwalan  阅读(1388)  评论(0编辑  收藏  举报