对于今日头条这家公司来说,测试的题和后端开发的题几乎是一样的,但是由于第一批的后端开发的题没有在牛客网上放出来,因此,猜测后端开发第一批的题应该和后端开发第一批的题一样,同时也想做一个测试方向编程题的汇总。
原题链接:
今日头条2018校招测试开发方向(第一批)
第一题:编程题1
题目:
P
为给定的二维平面整数点集。定义P
中某点x
,如果x满足 P 中任意点都不在x
的右上方区域内(横纵坐标都大于x
),则称其为“最大的”。求出所有“最大的”点的集合。(所有点的横坐标和纵坐标都不重复, 坐标轴范围在[0, 1e9)
内)
如下图:实心点为满足条件的点的集合。请实现代码找到集合P
中的所有 ”最大“ 点的集合并输出。
输入描述:
第一行输入点集的个数N
, 接下来N
行,每行两个数字代表点的 X 轴和 Y 轴。
对于 50%的数据, 1<=N<=10000 1 <= N <= 10000 ;
对于 100%的数据, 1<=N<=500000 1 <= N <= 500000 ;
解析:
抓住最大点的关键信息:在最大点的右上方没有其余点,这就意味着,如果当前点是最大点,那么在该点右边的所有点都比该点矮,这一点要理解,因为在该点左边的点无论如何都不会对该点是否为最大点有影响(原因看加粗字体);
先按X轴坐标从大到小排序(这是为了保证遍历过的点都在当前点的右边),然后依次遍历这些点,遍历的时候维护一个最大的Y轴坐标,这样子遍历到当前点时判断一下当前点的Y轴坐标是否大于最大的Y轴坐标,如果不大于,这说明在当前点的右上方有点,当前点就不是最大点;如果大于,那么说明当前点的右上方没有点,这个点就是最大点,同时更新最大的Y轴坐标。
时间复杂度: O(nlogn) O ( n l o g n ) 。
代码:
#include <bits/stdc++.h>
using namespace std;
bool cmpFirst(const pair<int, int> &A, const pair<int, int> &B)
{
return A.first > B.first;
}
int main()
{
for (int n; EOF != scanf("%d", &n); ) {
vector<pair<int, int> > arr;
vector<int> tmpArr;
for (int i = 0, x, y; i < n; i++)
scanf("%d%d", &x, &y), arr.emplace_back(x, y), tmpArr.push_back(y);
sort(arr.begin(), arr.end(), cmpFirst);
vector<pair<int, int> > ans;
for (int i = 0, theMax = 0; i < n; i++) {
if (arr[i].second > theMax)
ans.push_back(arr[i]), theMax = arr[i].second;
}
for (auto it = ans.rbegin(); it != ans.rend(); it++)
printf("%d %d\n", it->first, it->second);
}
return 0;
}
第二题:编程题2
题目:
给定一个数组序列, 需要求选出一个区间, 使得该区间是所有区间中经过如下计算的值最大的一个:
区间中的最小数 * 区间所有数的和最后程序输出经过计算后的最大值即可,不需要输出具体的区间。如给定序列[6, 2, 1]
则根据上述公式, 可得到所有可以选定各个区间的计算值:
[6] = 6 * 6 = 36;
[2] = 2 * 2 = 4;
[1] = 1 * 1 = 1;
[6,2] = 2 * 8 = 16;
[2,1] = 1 * 3 = 3;
[6, 2, 1] = 1 * 9 = 9;
从上述计算可见选定区间[6]
,计算值为 36, 则程序输出为 36。
区间内的所有数字都在[0, 100]
的范围内;
输入描述:
第一行输入数组序列长度n
,第二行输入数组序列。
对于 50%的数据, 1<=n<=10000 1 <= n <= 10000 ;
对于 100%的数据, 1<=n<=500000 1 <= n <= 500000 ;
解析:
先求出以当前点为最小值的最大子区间,这个可以用单调栈去求,如果还不清楚单调栈可以求这个东西,就要好好补补课了;然后预处理出前缀和;单调栈在入栈的时候能确定区间的左端点,而在出栈的时候能确定右端点,因此,在出栈的时候就维护一个最大值。这个最大值最后就是答案。
时间复杂度: O(n) O ( n ) 。
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
for (int n; EOF != scanf("%d", &n); ) {
vector<int> arr(n + 1, 0), sum(n + 1, 0);
for (int i = 1, x; i <= n; ++i) {
scanf("%d", &x);
arr[i] = x;
sum[i] = sum[i - 1] + x;
}
stack<pair<int, int> > st;
int ans = 0;
for (int i = 1; i <= n + 1; i++) {
for (; !st.empty() && arr[st.top().first] >= arr[i]; st.pop()) {
ans = max(ans, (sum[i - 1] - sum[st.top().second]) * arr[st.top().first]);
}
st.emplace(i, st.empty() ? 0 : st.top().first);
}
printf("%d\n", ans);
}
return 0;
}
今日头条2018校招测试开发方向(第二批)
详情见今日头条2018校园招聘后端开发工程师(第二批)编程题 - 题解。
今日头条2018校招测试开发方向(第三批)
详情见今日头条2018校园招聘后端开发工程师(第三批)编程题 - 题解。