今日頭條2018校招測試開發方向(第一、二、三、四批)程式設計題彙總
對於今日頭條這家公司來說,測試的題和後端開發的題幾乎是一樣的,但是由於第一批的後端開發的題沒有在牛客網上放出來,因此,猜測後端開發第一批的題應該和後端開發第一批的題一樣,同時也想做一個測試方向程式設計題的彙總。
原題連結:
今日頭條2018校招測試開發方向(第一批)
第一題:程式設計題1
題目:
P
為給定的二維平面整數點集。定義P
中某點x
,如果x滿足 P 中任意點都不在x
的右上方區域內(橫縱座標都大於x
),則稱其為“最大的”。求出所有“最大的”點的集合。(所有點的橫座標和縱座標都不重複, 座標軸範圍在[0, 1e9)
內)
如下圖:實心點為滿足條件的點的集合。請實現程式碼找到集合P
中的所有 ”最大“ 點的集合並輸出。
輸入描述:
第一行輸入點集的個數N
, 接下來N
行,每行兩個數字代表點的 X 軸和 Y 軸。
對於 50%的資料, ;
對於 100%的資料, ;
解析:
抓住最大點的關鍵資訊:在最大點的右上方沒有其餘點,這就意味著,如果當前點是最大點,那麼在該點右邊的所有點都比該點矮,這一點要理解,因為在該點左邊的點無論如何都不會對該點是否為最大點有影響(原因看加粗字型);
先按X軸座標從大到小排序(這是為了保證遍歷過的點都在當前點的右邊),然後依次遍歷這些點,遍歷的時候維護一個最大的Y軸座標,這樣子遍歷到當前點時判斷一下當前點的Y軸座標是否大於最大的Y軸座標,如果不大於,這說明在當前點的右上方有點,當前點就不是最大點;如果大於,那麼說明當前點的右上方沒有點,這個點就是最大點,同時更新最大的Y軸座標。
時間複雜度:。
程式碼:
#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%的資料, ;
對於 100%的資料, ;
解析:
先求出以當前點為最小值的最大子區間,這個可以用單調棧去求,如果還不清楚單調棧可以求這個東西,就要好好補補課了;然後預處理出字首和;單調棧在入棧的時候能確定區間的左端點,而在出棧的時候能確定右端點,因此,在出棧的時候就維護一個最大值。這個最大值最後就是答案。
時間複雜度:。
程式碼:
#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;
}